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.Completed
上e
参数将不会引发并且可以检查作为参数传递的e
对象后立即方法调用返回以检索操作的结果。