gpt4 book ai didi

c# - 判断一个TCP流是否已经断开

转载 作者:可可西里 更新时间:2023-11-01 02:52:10 24 4
gpt4 key购买 nike

我处于需要在我的监听器和 TCPClient 之间打开流的情况。流打开后,客户端将发送消息流,我将为每个消息发送一个 ACK​​。如果我在一定时间内(默认为 5 分钟)没有收到任何消息,我将断开与服务器的连接并返回监听新连接。

监听器应该只有一个客户端尝试与其通信。规范规定,在发送完所有消息之前,应该打开并保持流,这可能意味着设备会连接几天或更长时间。不幸的是,Client是第三方软件,我不能保证它不会在每条消息后关闭连接。

我的问题是,如何判断客户端是否已断开连接。我做了我的研究,知道这个问题已经有几个答案,但他们基本上说我需要写入流,如果有异常,连接已经关闭。我编写代码来执行此操作,但发现某些客户端未设置为处理非 ACK 的传入消息。到目前为止,我得到的都是记录的错误消息,但我担心这个“ping”可能会导致其中一个客户端崩溃。

我可以在每条消息后关闭连接,但至少有一个客户端将继续尝试发送一系列的所有消息,直到它们全部在单个流上被接收,因此它不适用于此解决方案。

我可以将 NetworkStream.ReadTimeout 设置为一个较小的值,例如 1 秒,但每次超时都会出现异常,并且使用异常进行流量控制不是好的代码(尽管我正在做一些) ping 时)。

下面是我现在所拥有的片段:

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
}
}

最佳答案

经过更多的搜索,我找到了如何从 TcpClient 访问套接字。有了这个之后,我就可以使用 Poll 来确认连接仍然打开。我的代码如下:

try
{
if (client.Client.Poll(1000, SelectMode.SelectRead) && client.Client.Available == 0)
{
isConnected = false;
}
}
catch (Exception)
{
// If an exception is thrown, then the connection is closed
isConnected = false;
}

如果连接关闭、重置、终止、挂起或有可用数据,Client.Poll 返回 true。如果检查 Client.Available,但没有数据,则必须关闭连接。这并非万无一失,但对我的目的有用,因为我只是回去听。

此解决方案来自 zendar,位于 here .

关于c# - 判断一个TCP流是否已经断开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20557424/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com