最近写了个Socket服务端程序,发现有时一直收到数据长度为0,而且Receive()函数也不阻塞。代码如下。
Socket clientConnection = (Socket) clientSocket;
while (_needReceive)
{
var rcvBytes = new byte[1024];
try
{
var length = clientConnection.Receive(rcvBytes);
var rcvStr = Encoding.UTF8.GetString(rcvBytes, 0, length);
ShowInfo($"接收到客户端:{rcvStr},length:{length}");
if (length > 0)
{
var response = "abcd";
var respBytes = Encoding.UTF8.GetBytes(response);
var ret = clientConnection.Send(respBytes);
ShowInfo($"发送到客户端:{response}");
}
}
catch (Exception e)
{
clientConnection.Close();
ShowInfo($"通讯失败:{e.Message}");
break;
}
}
客户端Socket执行了Close()方法后,服务端的Receive()方法,每次都接收到0个字节,并且不阻塞。
从一本书上看到以下描述,书名为C# Network Programming,作者Richard Blum。
The return value from the Receive() method has to be examined to see if the remote client disconnected from the session. This can be determined by detecting a zero return value. If the remote client disconnected, you must close the socket …
翻译下来就是,如果Receive()方法返回0,这个可以作为客户端关闭了的标志。因此程序改为如下即可。
Socket clientConnection = (Socket) clientSocket;
while (_needReceive)
{
var rcvBytes = new byte[1024];
try
{
var length = clientConnection.Receive(rcvBytes);
if (length > 0)
{
var rcvStr = Encoding.UTF8.GetString(rcvBytes, 0, length);
ShowInfo($"接收到客户端:{rcvStr},length:{length}");
string response = "abcd";
var respBytes = Encoding.UTF8.GetBytes(response);
var ret = clientConnection.Send(respBytes);
ShowInfo($"发送到客户端:{response}");
}
else
{
clientConnection.Close();
ShowInfo($"客户端关闭。");
break;
}
}
catch (Exception e)
{
clientConnection.Close();
ShowInfo($"通讯失败:{e.Message}");
break;
}