我正在开发一个使用 TCP 套接字的 C# 应用程序。
在调试时,我得到了这段源代码:
if ((_socket!= null) && (_socket.Connected))
{
Debug.WriteLine($"..."); <= my breakpoint is here.
return true;
}
在我的监 window 口中,_socket.RemoteEndPoint
的值是:
_socket.RemoteEndPoint {10.1.0.160:50001} System.Net.EndPoint {...}
仍然,在命令行中,当我运行 netstat -aon | findstr /I "10.1.0.160"
时,我刚刚看到这个:
TCP 10.1.13.200:62720 10.1.0.160:3389 ESTABLISHED 78792
TCP 10.1.13.200:63264 10.1.0.160:445 ESTABLISHED 4
=> 远程端点“10.1.0.160:50001”在 netstat
中不可见结果。
如netstat
测试 TCP 套接字似乎不可靠,我可以使用什么工具代替?
(供您引用:即使进一步运行后,仍然没有“netstat”条目。)
最佳答案
Socket.Connected 的文档,说:
The value of the Connected property reflects the state of the connection as of the most recent operation. If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.
因此,如果它返回 true - 套接字在过去的某个时间已“连接”,但现在没有必要仍处于事件状态。
这是因为如果不以某种方式联系另一方,就不可能检测到您的 TCP 连接是否仍然有效。 TCP 连接是一种“虚拟”连接,双方仅交换数据包,但它们之间没有硬链接(hard link)。当一侧决定完成通信时,它会发送一个数据包并等待另一侧的响应。如果一切顺利,双方都会同意关闭连接。
但是,如果 A 方不发送此关闭数据包,例如因为它崩溃了,或者互联网死机等等 - 另一方 B 无法确定连接不再处于事件状态,直到它尝试发送一些数据包数据到 A。那么这次发送将失败,现在 B 知道连接已断开。
因此,如果您确实需要知道另一方是否还活着 - 那么您必须向那里发送一些数据。您可以使用 TCP 套接字上可用的 keepalive(它的作用基本上相同 - 不时发送一些数据)。或者,如果您总是首先在此连接上写入(假设另一端是服务器,并且您不时向它发出请求,但不期望这些请求之间有任何数据) - 那么就不要检查另一端是否处于事件状态 -当你下次尝试写作时你就会知道。
关于c# - 验证套接字是否打开的可靠方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75109677/