2010-12-03 136 views
7

我使用的.Net的Socket類,我用下面的代碼:爲什麼.Net Socket.Disconnect需要兩分鐘?

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

這就塊整整兩分鐘。我指定了true,因爲我將立即重用套接字並重新建立連接。無論是否有關機呼叫,它都會阻塞兩分鐘。我能做的唯一事情就是傳遞錯誤來斷開連接。但我想重用套接字。

任何想法?

UPDATE:

我已閱讀代碼。我已經設置了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() 

跡線2:使用關機(SocketShutdown。都);

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() 
+0

我們可以看到一些周圍的代碼嗎?有可能是由於其他原因導致延遲,例如循環或阻塞呼叫。 – 2010-12-07 19:29:15

回答

-2

原來有一些註冊表項控制斷開連接需要多長時間。它與WinSock2 api有關。

0

這可能是靈兒選項。在這裏看到更多的信息:Graceful Shutdown, Linger Options, and Socket Closure

在.NET中,你可以改變它與Socket.SetSocketOption方法。

編輯:如果不是靈兒選項,你應該儘量使全窩痕跡,這裏是一個的.config樣本:

<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> 

編輯:或者你可以打什麼所謂的TIME_WAIT ,在這裏描述:Please explain the TIME_WAIT state這是120ms。使用Close()和SocketOptionName.ReuseAddress通常更好,而不是使用Disconnect(true)。請參閱註釋here(在評論部分中)。

+0

我已經嘗試設置DontLinger選項。這是行不通的。無論如何,我使用Socket.ShutDown,所以它不應該是必要的。 – uriDium 2010-12-03 13:59:17

+0

想法:嘗試啓用跟蹤(我已經更新了我的答案) – 2010-12-03 14:09:57

+0

我已經嘗試過不要逗留和關閉,並獲得相同的跟蹤。我用跟蹤更新了我的問題。 – uriDium 2010-12-03 14:21:34

1

這可能是你正在尋找的。

如果您需要致電斷開連接而不首先調用shutdown,您可以設置DontLinger Socket選項設置爲false,並指定一個非零的超時間隔,以確保數據排隊傳出傳輸發送。然後斷開連接,直到發送數據或直到指定的超時到期。如果將DontLinger設置爲false並指定零超時間隔,則Close會釋放連接並自動丟棄傳出的排隊數據。

docs

3

如果關閉,則在斷開連接或BeginDisconnect的情況下,如果另一端的套接字不是正在接收,將發生超時。

這裏它是如何工作的: Shutdown(SocketShutdown.Send)(或兩者)產生零字節的SENDING到另一端。 然後,如果您調用斷開連接,它將阻塞,直到另一方接受此零字節數據包。 這就是爲什麼套接字在從套接字正常斷開連接期間在接受期間始終接收零字節的原因。 靈隱選項和其他設置對這2分鐘的延遲沒有影響。您可以使用TCPView檢查連接狀態。 所以正確的方法是確保另一端處於接收模式或物理斷開連接或實際銷燬套接字 - 例如退出應用程序(在這種情況下,您將在沒有2分鐘延遲的情況下立即得到異常)。

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

相關問題