繁体   English   中英

C#中如何高效判断一个socket的状态?

[英]How to efficiently determine the status of a socket in C#?

我有一个从客户端接收数据的服务器,我希望能够确定套接字是否仍然连接。

我正在使用以下 function 来确定状态(来源):

bool SocketConnected(Socket s)
{
    bool part1 = s.Poll(1000, SelectMode.SelectRead);
    bool part2 = (s.Available == 0);
    if (part1 && part2)
        return false;
    else
        return true;
}

但是,当 RTT(服务器/客户端之间)很高(~300 毫秒)并且变化(+ - 60 毫秒)时,我的应用程序“崩溃”。 从调试中我发现这是由于套接字被标识为未连接(SocketConnected()返回false)。 但我知道,套接字仍然连接,因为我可以看到客户端流式传输从服务器请求的内容,并且服务器接收由 Wireshark 捕获的数据。

我应该增加轮询的时间(但我不想阻止其他操作)还是将 Socket.Connected 属性与 SocketConnected() 一起使用? 在不稳定的环境中确定套接字状态的最有效方法是什么?

不幸的是,您找到并引用的问题和答案充满了糟糕的建议,并且没有什么真正有建设性的问题可以说。 TCP 等面向连接的协议专门设计用于尽可能长时间地延迟错误,以尽可能多地解决潜在的间歇性传输问题(网络电缆被拔出、无线连接重置等),以尽量减少这些问题的影响在实际连接上。

对所引用问题的每一个答案都会破坏这一一般策略,或者未能以有用的方式解决问题,或者两者兼而有之。

处理这种情况的唯一正确方法是假设套接字在您期望的连接 state 中(基于您自己的代码操作),同时确保您的代码在每个适当的使用点都有异常处理的插座。 没有其他办法。

您可以查看Connected属性,但这不会告诉您任何有用的信息。 检查属性后,套接字可能会在一纳秒内转换为未连接的 state。 您也不应该使用Poll()等基于“选择”的方法,因为这些方法效率低下,并且不会随连接数量而扩展。

每个联网程序都可以成功使用异步 I/O。 如果程序有 GUI(例如 Winforms、WPF 等),那么您甚至可以这样做,同时仍然在 UI 线程中进行所有实际数据处理(这让您不必太担心多线程问题......使用现代的async / await习惯用法会更好,但您也可以只使用“老派”技术,如Control.BeginInvoke()Dispatcher.InvokeAsync() )。

因此,遵循这些准则,唯一一次套接字的连接性会以任何有意义、有趣的方式改变 state 是当这种情况有意发生时,然后通过正常处理优雅关闭来检测,即读取操作以零字节完成结果,或者由于错误而发生,在这种情况下,您的异常处理将检测到意外断开的 state。

如果没有适当的异常处理,您将无法成功编写无缺陷的网络 I/O 代码,因此只有依赖该异常处理来处理所有异常情况才有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM