2016-08-15 48 views
-3

首先,什麼我的計劃應該做的,如果它會工作:服務器/客戶端Socket連接問題

  1. 客戶端用C++編寫連接到服務器在C#編碼
  2. 當連接被成功後,客戶端發送「 0" 向服務器請求的十六進制數
  3. 的隨機字符串如果客戶收到他送的十六進制數‘1’到服務器
  4. 現在客戶做一些事情與收到Hexadecimalstring,然後將其發送回服務器
  5. 如果客戶做的Hexadecimalstring是正確的(基本驗證中系統),他將返回「1」,否則,他會返回「0」

注:recieving /發送的客戶端/服務器端的作品,我通過只發送1至服務器,服務器返回0之前,測試它,如果收到的字符串爲1

現在我的編碼: 那是用C#編寫的服務器部分:

private static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
private static List<Socket> clientSockets = new List<Socket>(); 
private const int PORT = 11111; 
private static byte[] buffer = new byte[100]; 

private void ReceiveCallback(IAsyncResult AR) 
{ 
    Socket current = (Socket)AR.AsyncState; 
    int received; 

    try 
    { 
     received = current.EndReceive(AR); 
    } 
    catch (SocketException) 
    { 
     Console.WriteLine("Client Disconnected! (Forced)"); 
     current.Close(); 
     clientSockets.Remove(current); 
     return; 
    } 
    //That's how my Example before worked: 
    /*byte[] recBuf = new byte[1]; 
    Array.Copy(buffer, recBuf, received); 
    string text = Encoding.ASCII.GetString(recBuf); 
    if(text != "" && text.StartsWith("0")) 
    { 
     Console.WriteLine("Recieved: " + text); 
     string send = "1"; 
     Console.WriteLine("Sending: " + send); 
     Byte[] data = ASCIIEncoding.ASCII.GetBytes(send); 
     current.Send(data); 
     Console.WriteLine("Sended!"); 
     current.Shutdown(SocketShutdown.Both); 
     current.Close(); 
     clientSockets.Remove(current); 
     Console.WriteLine("Client Disconnected!"); 
     return; 
    } 
    current.BeginReceive(buffer, 0, 1, SocketFlags.None, ReceiveCallback, current);*/ 
    //worked like a charm! 
    //That's my new Solution, that doesn't work: 
    byte[] recBuf = new byte[100]; 
    Array.Copy(buffer, recBuf, received); 
    string text = Encoding.ASCII.GetString(recBuf); 
    while (text != "") 
    { 
     Console.WriteLine("Received Data: " + text); 
     if (text.StartsWith("0") && text.Length < 32) 
     { 
      Console.WriteLine("Client requests Random HexString..."); 
      string rand = GetRandomHexNumber(32); 
      Byte[] data = ASCIIEncoding.ASCII.GetBytes(rand); 
      current.Send(data); 
      Console.WriteLine("Sended HexString! - " + rand); 
     } 
     if (text.StartsWith("1") && text.Length < 32) 
     { 
      Console.WriteLine("Client recieved the HexString!"); 
     } 
     if (text.Length > 32 && !text.StartsWith("0") && !text.StartsWith("1")) 
     { 
      Console.WriteLine("Result recieved!"); 
      //here will be some authing process but for simplicity just return "1" 
      byte[] data = ASCIIEncoding.ASCII.GetBytes("1"); 
      current.Send(data); 
      current.Shutdown(SocketShutdown.Both); 
      current.Close(); 
      clientSockets.Remove(current); 
      Console.WriteLine("Client Disconnected!"); 
      return; 
     } 
     if (current.Connected) 
      current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current); 
    } 
    if (current.Connected) 
     current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current); 
} 

private void AcceptCallback(IAsyncResult AR) 
{ 
    Socket socket; 

    try 
    { 
     socket = serverSocket.EndAccept(AR); 
    } 
    catch (ObjectDisposedException) 
    { 
     return; 
    } 

    clientSockets.Add(socket); 
    socket.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, socket); 
    Console.WriteLine("Client Connected!"); 
    serverSocket.BeginAccept(AcceptCallback, null); 
} 

private void setupServer() 
{ 
    serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT)); 
    serverSocket.Listen(0); 
    Console.WriteLine("Server Started!"); 
    Console.WriteLine("Listening for Clients..."); 
    serverSocket.BeginAccept(AcceptCallback, null); 
} 

private void CloseAllSockets() 
{ 
    foreach (Socket socket in clientSockets) 
    { 
     socket.Shutdown(SocketShutdown.Both); 
     socket.Close(); 
    } 

    serverSocket.Close(); 
} 

setupServer();在控制檯啓動時啓動! C#部分是唯一有問題的C++端一切都很好! 我真的希望有人能夠幫助我,因爲我在這個論壇上還沒有收到任何幫助,我確實需要這個工作,我確定這裏有很多可以幫助你的程序員。我(也許它只是一個合乎邏輯的問題,所以每一個回答或評論表示讚賞) 感謝您的時間:)

+2

如果您對您的問題不滿意,請將其刪除。不要刪除其內容。 – molbdnilo

+0

@molbdnilo如果問題有答案,它不能被刪除!我只是不想向其他人展示可能搜索我如何做我的服務器來查看我的代碼,那就是爲什麼我修改它... –

+0

@DamnDaniel,但他們仍然可能會看到修訂歷史中的代碼...我會建議改變這個問題,以便它1)概括了你的代碼的本質(即''while''帶'BeginReceive()'循環是強制性的;你收到的消息處理的細節可以省略)並且2)描述了它的不正確的行爲(我希望應用程序在收到第一條消息後會陷入無限循環)。 (待續...) –

回答

0

更換

while (text != "") 
{ 
    // ..................... 
    if (current.Connected) 
     current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current); 
} 
if (current.Connected) 
    current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current); 

if (text != "") 
{ 
    // ..................... 
    // Notice there's no BeginReceive() here! 
} 
if (current.Connected) 
    current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current); 

的功能callback paramat傳遞呃到BeginReceive()通常不應該在循環中調用BeginReceive()「直到會話結束」。相反,如果預期會有更多的數據(即「未完成的會話」),它應該僅調用 一次以掛起另一個讀取操作。

+0

謝謝工作完美:) –