我正在使用异步TCP服务器/客户端通信。我在日志中注意到同一个客户端多次重新连接。但是,它从未表明它已断开连接。我的代码记录了连接和断开连接。那么为什么readAsync在客户端断开连接时保持循环?以下是供您参考的代码:
private async Task Accept(TcpClient client)
{
//get client information
string clientEndPoint = GetClientIPAddress(client);
log.Info("Client connected at " + clientEndPoint); //same client is connected several times in log
await Task.Yield ();
try
{
using (client)
using (NetworkStream stream = client.GetStream ())
{
byte[] dataReceived = new byte [100];
while (await stream.ReadAsync(dataReceived, 0, dataReceived.Length) != 0) //read input stream - 0=>end of stream is reached
{
//pass on data for processing
var task = ProcessData(dataReceived);
}
}
log.Info("Closing client connection " + clientEndPoint);//this line is never reached in log
if (client.Connected)
client.Close();
} //end try
catch (Exception ex)
{
log.Error(ex.Message);
log.Info("Closing client connection " + clientEndPoint);
if (client.Connected)
client.Close();
}
答案 0 :(得分:2)
看起来你可能有一个半开放的问题。您应该定期写入数据以确定套接字是否仍然连接;读取可以检测到正常关闭,但不能检测半开放场景。
我在博客上更多地描述了half-open problem。
答案 1 :(得分:0)
您是否检查过TCP keep alive
是否已设定?这应该检测连接是否被破坏。
另外,检查接收时是否有零长度字节,这意味着连接已关闭。
编辑:Keep Alive是检查连接是否处于活动状态的标准方法,这意味着一方定期向另一方发送小块数据:http://en.wikipedia.org/wiki/Keepalive。
许多组件已经实现了此功能。我从来没有使用TcpClient
类,但它必须是Socket
通过TCP的一些包装类,并且正如doc所说,这个类暴露了底层Socket
(你可以使用{{1 } Socket
的类也是,但没关系)。这个TCP
有方法Socket
。所以试试:
SetSocketOption