Why does .Net Socket.Disconnect take two minutes?

前端 未结 5 2037
庸人自扰
庸人自扰 2020-12-31 18:29

I am using .Net\'s socket class and I am using the following code:

socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(true);

This then

相关标签:
5条回答
  • 2020-12-31 19:05

    That may be to the Linger option. See here for more information: Graceful Shutdown, Linger Options, and Socket Closure

    in .NET, you can change it with the Socket.SetSocketOption method.

    EDIT: if it's not the Linger option, you should try to enable full socket traces, here is a .config sample:

    <configuration>
      <system.diagnostics>
        <trace autoflush="true" />
        <sources>
          <source name="System.Net.Sockets">
            <listeners>
              <add name="SocketsTrace"/>
            </listeners>
          </source>
        </sources>
    
        <sharedListeners>
          <add name="SocketsTrace" type="System.Diagnostics.TextWriterTraceListener" initializeData="SocketsTrace.log" />
        </sharedListeners>
    
        <switches>
          <add name="System.Net.Sockets" value="Verbose" />
        </switches>
     </configuration>
    

    EDIT: or you can hit what's called the TIME_WAIT, described here: Please explain the TIME_WAIT state which is 120ms. It's generally better to use Close() with the SocketOptionName.ReuseAddress rather than to use Disconnect(true). See comments here as well (in the comments section).

    0 讨论(0)
  • 2020-12-31 19:08

    This might be what you are looking for.

    If you need to call Disconnect without first calling Shutdown, you can set the DontLinger Socket option to false and specify a nonzero time-out interval to ensure that data queued for outgoing transmission is sent. Disconnect then blocks until the 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.

    From the docs.

    0 讨论(0)
  • 2020-12-31 19:11

    Timeout in case of Shutdown followed by Disconnect or BeginDisconnect will occur in the case if the other side Socket is not Receiving.

    Here how it works: Shutdown(SocketShutdown.Send) (or Both) produce SENDING of zero byte to other side. And then if you call Disconnect it will block until other side accept this zero byte packet. This is why socket always receive zero byte during in Accept during graceful disconnection from Socket. Linger option and other settings have no effect on this 2 minute delay. You may check connection state with TCPView. So proper way is to make sure other side is either in Receive mode OR physically disconnected OR actually destroyed socket - for example application quit (you will get immediate exception in this case without 2 minute delay).

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

    0 讨论(0)
  • 2020-12-31 19:13

    It takes 2 min because the server probably did'nt close the socket when it received 0 bytes from the shutdown call of the client.

    So client call shutdown. The server receive 0 bytes. Client call Disconnect : disconnect will wait the close of the socket from the server side. If the server don't close the socket, the disconnect of the client will take 2 min (timeout). If the server close the socket, the disconnect will be almost immediate.

    0 讨论(0)
  • 2020-12-31 19:16

    Turns out there is some registry entry which controls how long a disconnect takes. It has something to do with the WinSock2 api.

    0 讨论(0)
提交回复
热议问题