我想你可能會太快。
大多數操作系統在任何時候都可以打開的套接字數量有限制,但實際上這比其更糟。
當套接字關閉時,它會處於特定的時間等待狀態一段時間。這通常是數據包生存時間值的兩倍,並且可以確保網絡中沒有數據包正在通往套接字的路徑中。
一旦該時間到期,您可以確定網絡中的所有數據包已經死亡。套接字被置於特殊狀態,以便在關閉網絡時在網絡中傳出的數據包可以在它們死亡之前到達時被捕獲並丟棄。
我認爲這就是你的情況,套接字沒有像你想象的那樣被快速釋放。
我們有一個類似的代碼打開了很多短暫的會話問題。它運行良好一段時間,但隨後硬件變得更快,允許在給定的時間段內打開更多的硬件。這表現爲無法開放更多會議。
檢查此的一種方法是從命令行執行netstat -a
並查看有多少會話實際處於等待狀態。
如果情況確實如此,有幾種方法可以處理它。
- 重新使用您的會話,無論是手動或通過維護連接池。
- 在每個連接中引入延遲嘗試並停止達到飽和點。
- 直到你達到飽和,然後然後修改你的行爲,比如在一個while語句內運行你的連接邏輯,每次在完全放棄之前每次重試最多60次,延遲時間爲2秒。這可以讓您全速運行,只有在出現問題時纔會放慢速度。
這最後的子彈一點值得一些擴展。實際上,我們在上述應用中使用了一種退避策略,如果它在抱怨,那麼它將逐漸減少資源提供者的負載,而不是30秒的延遲,我們選擇延遲一秒,然後選擇兩秒,然後是四個等等。
退避策略的一般過程如下,它可以用於資源可能暫時短缺的任何情況。在下面的僞代碼中提到的動作就是在你的情況下打開一個套接字。
set maxdelay to 16 # maximum time period between attempts
set maxtries to 10 # maximum attempts
set delay to 0
set tries to 0
while more actions needed:
if delay is not 0:
sleep delay
attempt action
if action failed:
add 1 to tries
if tries is greater than maxtries:
exit with permanent error
if delay is 0:
set delay to 1
else:
double delay
if delay is greater than maxdelay:
set delay to maxdelay
else:
set delay to 0
set tries to 0
這使得處理能夠以全速在絕大多數情況下運行,但回退時的錯誤開始發生,希望給資源提供者的時間來恢復。延遲的逐漸增加允許更嚴重的資源限制來恢復,並且最大的嘗試可以捕捉到您所稱的永久性錯誤(或需要很長時間才能恢復的錯誤)。
你必須配置插座TIME_WAIT等相關paramters根據不同的操作系統(機器要連接到) – 2009-07-06 06:37:50
它並不總是一個好主意,用這些參數撥弄。大多數應該針對網絡特性進行調整,然後您的應用程序應該進行調整。在不減少生存時間的情況下減少time_wait將導致虛假數據包到達。將TTL減少到數據包無法到達目的地意味着大量丟棄的數據包。理想情況下,您應該保持連接處於打開狀態(手動或連接池)或調整應用程序行爲(例如在他的回答中提及@Stu提及的延遲)。 – paxdiablo 2009-07-06 06:40:44