【问题标题】:How to detect TCP connection failure using NetworkStream.DataAvailable property?如何使用 NetworkStream.DataAvailable 属性检测 TCP 连接失败?
【发布时间】:2020-08-18 20:41:01
【问题描述】:

在 TCP 使用Socket 时,在连接丢失时尝试读取数据将引发异常。 我习惯于使用异常来了解 TCP 操作何时失败,因为除了尝试读/写之外,您无法可靠地判断连接已断开。

但我刚刚注意到NetworkStream.DataAvailable 在这种情况下只是返回false,而TcpClient.GetStream 也成功返回。我有如下代码(在轮询循环中使用) - 有没有办法扩展这种方法来检测失败的连接?

    public int Read()
    {
        var stream = tcp.GetStream();
        if (!stream.DataAvailable)
            return 0;
        else
            return stream.Read(InBuffer, 0, InBuffer.Length);
    }

如果不是,那么我将不得不使用超时调用 Read 方法之一 - 这让我想知道 DataAvailable 的意义何在,因为它很容易导致无法检测到失败连接的错误。

【问题讨论】:

    标签: c# .net tcplistener


    【解决方案1】:

    没有。

    你看,当连接断开时你会得到一个异常。

    DataAvailable 目前可能根本没有可用的数据。数据包需要时间来传输,数据包可能会丢失。 TCP 有一种重新发送列表数据包的机制,但它会导致延迟。

    GetStream 返回流。这是您的端点。它在连接可用时返回它,这是有道理的。 DataAvailable 用于检查是否有数据等待。数据未等待不是连接丢失 - 它是数据未等待。

    【讨论】:

    • 是的,这是有道理的……但它让DataAvailable 看起来有点危险。如果您在读取数据之前等待数据,并且连接丢失,您永远不会知道。另一方面,如果您尝试Read 数据,这 导致异常,那么DataAvailable 的用途是什么 - 您已经知道有来自Read 尝试的数据
    • DataAvailable 允许您查看是否存在 - 猜猜看,数据可用。它是“我不需要处理还没有数据而不是等待的套接字”的一部分。检查是否有数据,然后读取那里的数据。你怎么能明智地编写一个拥有 30k 开放连接的服务器?
    • 所以这个属性可能只对服务器真正有用,而不是客户端。服务器可以期望客户端重新连接(并注意这是对现有连接的欺骗),但等待服务器的客户端负责检查套接字是否正常,因为服务器不会重新连接。
    • 并非如此。看,如果您读取数据,则无法保证您获得所有数据 - 所以如果您读取,只要 DataAvailable = true,您就会在循环中读取。然后等待下一个数据。
    猜你喜欢
    • 2021-12-28
    • 2011-06-13
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    相关资源
    最近更新 更多