2013-08-22 72 views
1

首先,我想說的是,這個代碼與客戶機/服務器工作正常,我的PC(客戶端和服務器在同一臺PC上運行)上C#:問題與插座ReceiveAsync和SendAsync遠程主機

問題開始時我在專用服務器上託管服務器。第二次我嘗試發送或接收與客戶端,客戶端將花費很多時間來完成操作(談論接收1個字節的數據,需要超過1小時!)

**我可以避免這種情況通過簡單地切斷和每個發送/接收命令

我不明白爲什麼需要這麼多的時間,如果我會做更多的則1個發送/同一個連接會話中接收操作後重新連接插座的問題。


下面是一個例子:

連接的服務器:

RC_Server = new SocketConnection_Client(RC_IpEndPoint); 

現在客戶端連接到服務器,並且我就可以開始發送/接收正常。

第一次,我嘗試發送或接收它的作品完美和快速(無論緩衝區長度)。

RC_Server.sendCompleted = false; 
    RC_Server.Send(buffer); //in this case buffer size is 1024 
    while (!RC_Server.sendCompleted) { } //here thread is waiting for the send to complete 

現在,如果我想與服務器

 RC_Server.receiveCompleted = false; 
     RC_Server.Receive(buffer.Length); //in this case byffer needs to get 4 bytes from server 
     while (!RC_Server.receiveCompleted) { } // <<- Here it will take VERY long time for the operation to complete 
     buffer = RC_Server.buffer; 

第二接收操作永遠到不了socket_receiveCompleted_Completed事件開始接收會話。


但..如果我將關閉先發後服務器的連接/接收會話,然後打開與服務器的新連接,然後做下發送/接收會話, 那麼一切都會很好地工作。 (和多次重複這種方法對多個發送/接收)

再次,沒有在我的工作站出現問題(如果我在同一臺PC上運行的服務器和客戶端)。它只發生在我將服務器託管在遠程主機上時。

這裏是我的Socket類的一部分:

class SocketConnection_Client 
    { 
     public string errorMsg = string.Empty; 
     public bool receiveCompleted = false; 
     public bool sendCompleted = false; 
     int bytesReceived = 0; 
     public byte[] buffer; 
     Socket socket; 

     public SocketConnection_Client(IPEndPoint ipEP) 
     { 
      socket = new Socket(ipEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
      try 
      { 
       socket.Connect(ipEP); 
      } 
      catch (Exception ex) 
      { 
       errorMsg = ex.Message; 
       socket.Dispose(); 
       socket = null; 
      } 
     } 

     public void Send(byte[] sBuffer) 
     { 
      buffer = null; 
      if (socket == null) 
      { 
       sendCompleted = true; 
       return; 
      } 
      sendCompleted = false; 

      SocketAsyncEventArgs socket_sendCompleted = new SocketAsyncEventArgs(); 
      socket_sendCompleted.SetBuffer(sBuffer, 0, sBuffer.Length); 
      socket_sendCompleted.Completed += socket_sendCompleted_Completed; 
      socket.SendAsync(socket_sendCompleted); 
     } 

     void socket_sendCompleted_Completed(object sender, SocketAsyncEventArgs e) 
     { 
      sendCompleted = true; 
     } 

     public void Receive(int bLength) 
     { 
      bytesReceived = 0; 
      buffer = null; 
      if (socket == null) 
      { 
       receiveCompleted = true; 
       return; 
      } 
      receiveCompleted = false; 

      buffer = new byte[bLength]; 
      SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs(); 
      socket_receiveCompleted.SetBuffer(buffer, 0, buffer.Length); 
      socket_receiveCompleted.Completed += socket_receiveCompleted_Completed; 
      socket.ReceiveAsync(socket_receiveCompleted); 
     } 

     private void Receive_Continue() 
     { 
      SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs(); 
      socket_receiveCompleted.SetBuffer(buffer, bytesReceived, buffer.Length - bytesReceived); 
      socket_receiveCompleted.Completed += socket_receiveCompleted_Completed; 
      socket.ReceiveAsync(socket_receiveCompleted); 
     } 

     void socket_receiveCompleted_Completed(object sender, SocketAsyncEventArgs e) 
     { 
      bytesReceived += e.BytesTransferred; 
      if (e.BytesTransferred == 0 && bytesReceived == 0) 
      { 
       socket.Dispose(); 
       socket = null; 
       receiveCompleted = true; 
       throw new Exception("Server Disconnected"); 
      } 
      else if (bytesReceived != buffer.Length) 
       Receive_Continue(); 
      else 
       receiveCompleted = true; 
     } 
    } 

讚賞。 謝謝。

回答

0

您忽略ReceiveAsync的返回值。注意the documentation - 有兩種可能的行爲,必須檢查返回值來區分它們:

返回如果I/O操作掛起真。在操作完成後將會引發參數SocketAsyncEventArgs.Completed上的e事件。

如果I/O操作同步完成,則返回false。在這種情況下,事件SocketAsyncEventArgs.Completede參數將不會引發並且可以檢查作爲參數傳遞的e對象後立即方法調用返回以檢索操作的結果。