c# - 是否存在 TcpClient.Close 或 Socket.Close(0) 可能阻止我的代码的情况?

标签 c# sockets tcpclient

由于没有指定 Close 方法是线程安全的,我应该从锁中调用它。我如何确定它不会阻塞我的线程?我应该禁用 LingerState 还是可以启用它?

顺便说一句,我需要同时调用 TcpClient.Close 和 TcpClient.Client.Close 吗?

最佳答案

根据documentation for TcpClient.Close ,调用此方法会释放该实例。快速浏览一下 ILSpy 就会发现,它只是调用 Dispose,而后者又调用 Dispose(true)

此外,文档指出调用 Close 还会释放底层 Socket

事实上,在处置 Socket 之前,它会调用 Shutdown(SocketShutdown.Both) .

鉴于 .NET 套接字是 Windows 套接字的包装器,shutdown函数也被调用,其文档说明:

Note The shutdown function does not block regardless of the SO_LINGER setting on the socket.

但是,Socket 会重载其 Close 方法来接受 timeout 参数,并且与 TcpClient 类似, Socket.Close 方法调用 Socket.Dispose(true),它使用 timeout 值来确定是否可以阻塞。

根据documentation for Socket.Close(int) :

If you need to call Close without first calling Shutdown, you can ensure that data queued for outgoing transmission will be sent by setting the DontLinger option to false and specifying a non-zero time-out interval. Close will then block until this data is sent or until the specified time-out expires. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.

显然,TcpClientSocket 都没有将 timeout 值作为可设置属性向您公开,并且默认值不是 0 ;因此,为了避免阻塞,您必须在调用 TcpClient.Close 之前自行调用 Socket.Close(0)

请记住,Close 也可能引发 SocketException,尽管框架设计指南建议永远不要引发对 Dispose 的调用。也许这就是它被命名为 CloseTcpClient 显式实现 Dispose 方法的原因之一。

关于c# - 是否存在 TcpClient.Close 或 Socket.Close(0) 可能阻止我的代码的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25811286/

相关文章:

.net - 在 .NET 中关闭另一端时如何关闭 TcpClient?

C#配置TCPClient客户端端口

c# - 在 DatagridView 中添加/删除/选择 ComboBox 的值

c# - 如何使用 TcpChannel 配置对远程服务器的并发请求限制

python - 在python中获取ipv6地址不起作用

java - 在Java中获取传入输入流的IP

java - Android套接字等待问题

c# - 我可以让一个类在内部不密封但在外部密封吗?

c# - Visual Studio 不会在崩溃时进行调试

c# - 在网络流上安全超时 ReadLine