【发布时间】:2013-12-31 16:27:50
【问题描述】:
我需要在我的侦听器和 TCPClient 之间打开一个流。一旦流打开,客户端将发送一个消息流,我将为每个消息发送一个 ACK。如果我在设定的时间内(默认为 5 分钟)没有收到任何消息,我将断开与服务器的连接并返回侦听新连接。
侦听器应该只有一个尝试与之通信的客户端。规范规定应该打开并保持一个流,直到所有消息都发送完毕,这可能意味着设备连接了几天或更长时间。不幸的是,客户端是第三方软件,我不能保证它不会在每条消息后关闭连接。
我的问题是,如何判断客户端是否已断开连接。我做了研究,知道这个问题已经有几个答案了,但他们基本上说我需要写入流,如果有异常,连接已经关闭。我编写了代码来执行此操作,但发现某些客户端未设置为处理不是 ACK 的传入消息。到目前为止,我得到的只是记录的错误消息,但我担心这个“ping”可能会导致其中一个客户端崩溃。
我可以在每条消息之后关闭连接,但至少有一个客户端将继续尝试发送一系列消息,直到它们都在单个流上被接收到,因此它不适用于此解决方案。
我可以将 NetworkStream.ReadTimeout 设置为 1 秒之类的小值,但每次超时都会出现异常,并且使用异常进行流控制不是好的代码(尽管我正在做一些ping 时)。
下面是我现在拥有的sn-p:
while (bytesRead == 0 && isConnected && isListening)
{
if (stream.CanRead && stream.DataAvailable)
bytesRead = stream.Read(receivedBytes, 0, BufferSize);
else
{
if (++pingCount % 100 == 0)
{
// Ping the server every 10 seconds to confirm the connection
pingCount = 0;
try
{
stream.Write(ping, 0, ping.Length);
// client.Connected gives the status of the connection at the last communication
if (!client.Connected)
isConnected = false;
}
catch (Exception)
{
// If an exception is thrown, then the connection is closed
isConnected = false;
}
}
Thread.Sleep(100); // Wait and try again
}
}
【问题讨论】:
-
这听起来是一场灾难。如果你不能就这些非常基本的事情达成一致,那么你将有一段时间让它发挥作用。写一个规范,让它变得艰难。
-
我同意如果我们能做到这一点会容易得多,但我们正在与几个不同的预先存在的客户合作,并且需要尽可能通用,因为我们不知道什么软件将发送消息,仅发送消息内容。
标签: c# tcpclient tcplistener tcp-ip networkstream