为什么.Net Socket.Disconnect需要两分钟?

uri*_*ium 8 .net sockets

我正在使用.Net的socket类,我使用以下代码:

socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(true);
Run Code Online (Sandbox Code Playgroud)

然后这会阻塞两分钟.我已经指定了true,因为我将立即重用套接字并重新建立连接.我是否在那里有关机呼叫,它会阻塞两分钟.我唯一能做的就是传递false来断开连接.但我想重用套接字.

有任何想法吗?

更新:

我看过这些代码.我已经设置了DontLinger选项.它没有帮助.

更新2:

我已根据请求添加了网络跟踪:

跟踪1:使用DontLinger选项

System.Net.Sockets Verbose: 0 : [4668] Socket#5009246::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [4668] Exiting Socket#5009246::Socket() 
System.Net.Sockets Verbose: 0 : [4668] Socket#5009246::Connect(eee:nnnn#-2063562120)
System.Net.Sockets Information: 0 : [4668] Socket#5009246 - Created connection from aaa.bbb.ccc.ddd.eee:nnnnn to www.xxx.yyy.zzz.:mmmm.
System.Net.Sockets Verbose: 0 : [4668] Exiting Socket#5009246::Connect() 
System.Net.Sockets Verbose: 0 : [4668] Socket#5009246::Disconnect()
System.Net.Sockets Verbose: 0 : [4668] Exiting Socket#5009246::Disconnect() 
Run Code Online (Sandbox Code Playgroud)

跟踪2:使用关机(SocketShutdown.Both);

System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Socket() 
System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Connect(ddd:eeeee#-2063562120)
System.Net.Sockets Information: 0 : [0300] Socket#5009246 - Created connection from aaa.bbb.ccc.ddd:eeee to www.xxx.yyyy.zzzz:nnnnn.
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Connect() 
System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Shutdown(Both#2)
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Shutdown() 
System.Net.Sockets Verbose: 0 : [0300] Socket#5009246::Disconnect()
System.Net.Sockets Verbose: 0 : [0300] Exiting Socket#5009246::Disconnect() 
Run Code Online (Sandbox Code Playgroud)

Kon*_*tov 5

如果对方 Socket 没有接收,则在关闭后断开连接或开始断开连接时会发生超时。

下面是它的工作原理:Shutdown(SocketShutdown.Send)(或两者)产生零字节发送到另一端。然后,如果您调用 Disconnect,它将阻塞,直到另一端接受这个零字节数据包。这就是为什么在与 Socket 优雅断开连接期间,套接字在 Accept 期间总是接收到零字节。Linger 选项和其他设置对这 2 分钟的延迟没有影响。您可以使用 TCPView 检查连接状态。因此,正确的方法是确保另一端处于接收模式或物理断开连接或实际损坏的套接字 - 例如应用程序退出(在这种情况下,您将立即得到异常,没有 2 分钟的延迟)。

http://vadmyst.blogspot.ru/2008/04/proper-way-to-close-tcp-socket.html


uri*_*ium -3

事实证明,有一些注册表项可以控制断开连接所需的时间。它与WinSock2 api 有关。