(轉)
TIME_WAIT狀態
根據TCP協議定義的4次握手斷開連接規定,發起socket主動關閉的一方socket將進入TIME_WAIT狀態,TIME_WAIT狀態將持續2個MSL(Max Segment Lifetime),在Windows下默認為4分鐘,即240秒,TIME_WAIT狀態下的socket不能被回收使用. 具體現象是對于一個處理大量短連接的服務器,如果是由服務器主動關閉客戶端的連接,將導致服務器端存在大量的處于TIME_WAIT狀態的socket,甚至比處于Established狀態下的socket多的多,嚴重影響服務器的處理能力,甚至耗盡可用的socket,停止服務. TIME_WAIT是TCP協議用以保證被重新分配的socket不會受到之前殘留的延遲重發報文影響的機制,是必要的邏輯保證.
可以用如下代碼嘗試關閉TIME_WAIT,但這樣作是很危險的,違背TCP協議的,也不一定有效果.
linger InternalLinger = { 1, 0 };
::setsockopt(socket, SOL_SOCKET, SO_LINGER, (const char*)&InternalLinger, sizeof(linger));
中庸的做法是,可在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名為TcpTimedWaitDelay的
DWORD鍵,設置為30-240,以縮短TIME_WAIT的等待時間,這也是對IIS服務器的優化手段之一.編程上,除非必要,應盡量讓客戶端發起斷開操作.