.NET 7中如何识别TCP连接是否已关闭?

问题描述 投票:0回答:2

在 .NET 7 中识别 TCP 连接是否已关闭(正常与否)的正确方法是什么?我尝试使用 Socket.Poll 方法,但它不起作用。在 Socket.Poll 的文档中,我发现了这个注释:

This method cannot detect certain kinds of connection problems, such as a broken network cable, or the remote host being shut down ungracefully. You must attempt to send or receive data to detect these kinds of errors.

来源 -> https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.poll?view=net-7.0

我如何尝试接收数据来检测这些错误?我已经尝试过 NetworkStream.Read 和 NetworkStream.ReadAsync,但无法检测到任何错误。

c# sockets tcpclient networkstream
2个回答
1
投票

关闭 TCP 套接字是一个双方同意的过程,您通常有一个消息协议告诉另一端它正在关闭,或者您有一些预定义的指令集,然后您就关闭。

100% 检测远程套接字是否关闭的唯一可靠方法是向其发送一些数据。只有当您返回错误时,您才会知道套接字是否已关闭。

一些不发送大量数据的应用程序实现保持活动协议,它们只是每分钟发送/接收几个字节,因此它们知道远程端点存在。

从技术上讲,您可以拥有两台处于连接状态并且 10 年没有相互发送数据的服务器。每一端都继续相信另一端在那里,直到尝试发送一些数据并发现另一端不存在。

请注意,您可能必须发送数据两次,在第二次发送时收到套接字异常才能知道端点已消失。


0
投票

识别 TCP 连接是否已建立的正确方法是什么 关门了?

@ProgrammingLlama 你是如何尝试 Read 和 ReadAsync 的?你会期望 读取0字节

正确。检查先前连接的套接字上接收到的 0 字节。这是唯一的系统指标。另一方已关闭套接字,您应该在您这边调用 Disconnect 或 DisconnectAsync。当然,你可以从你这边调用socket Disconnect来终止socket连接,这将向对方发送相同的0字节消息。

@ProgrammingLlama - 0 字节的东西应该可以工作,当 连接被优雅地关闭。不幸的是,至少就我而言, 等待数据大约 20 分钟后,Read 和 ReadAsync 都停止 返回 0 字节。读取返回 IOException,代码为“超时”并且 ReadAsync 不返回任何内容。我想等多久都可以,但是 套接字仍处于“已连接”状态,轮询工作正常并且在那里 没有任何错误的迹象。

如果收到 0 字节,您将无法再使用该套接字。如果在该套接字上调用 Read 或 ReadAsync,则应引发异常。您只需致电 socket.Connected 查看关闭的套接字是否已连接,但在这种情况下它应该始终指示未连接。民意调查似乎没有帮助。如果网络或计算机出现故障,则不会发生关闭,因此需要如上所述的看门狗 Ping。

© www.soinside.com 2019 - 2024. All rights reserved.