C#:问题与插座ReceiveAsync和SendAsync远程主机

问题描述:

首先,我想说的是,这个代码与客户机/服务器工作正常,我的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; 
     } 
    } 

赞赏。 谢谢。

您忽略ReceiveAsync的返回值。注意the documentation - 有两种可能的行为,必须检查返回值来区分它们:

返回如果I/O操作挂起真。在操作完成后将会引发参数SocketAsyncEventArgs.Completed上的e事件。

如果I/O操作同步完成,则返回false。在这种情况下,事件SocketAsyncEventArgs.Completede参数将不会引发并且可以检查作为参数传递的e对象后立即方法调用返回以检索操作的结果。