TCP交互狀態(tài)示意圖
問題來源
毫無疑問,TCP中有關(guān)網(wǎng)絡(luò)編程最不容易理解的是它的TIME_WAIT狀態(tài)涮总。在圖中我們看到執(zhí)行主動關(guān)閉的那端經(jīng)歷了這個狀態(tài)胸囱。該端點停留在這個狀態(tài)的持續(xù)時間是最長分節(jié)生周期(maximumsegmentlifetime,MSL)的兩倍瀑梗,有時候稱之為2MSL烹笔。
任何TCP實現(xiàn)都必須為MSL選擇一個值裳扯。RFC1122[Braden1989]的建議值是2分鐘,不過源自Berkeley的實現(xiàn)傳統(tǒng)上改用30秒這個值谤职。這意味著TIME_WAIT狀態(tài)的持續(xù)時間在1分鐘到4分鐘之間饰豺。
TIME_ WAIT狀態(tài)有兩個存在的理由:
(1)可靠地實現(xiàn)TCP全雙工連接的終止;
通過查看圖2-5并假設(shè)最終的ACK丟失了來解釋允蜈。服務(wù)器將重新發(fā)送它的最終那
個FIN冤吨,因此客戶必須維護狀態(tài)信息,以允許它重新發(fā)送最終那個ACK饶套。要是客
戶不維護狀態(tài)信息漩蟆,它將響應(yīng)以一個RST(另外一種類型的TCP分節(jié)),該分
節(jié)將被服務(wù)器解釋成一個錯誤妓蛮。
如果TCP打算執(zhí)行所有必要的工作以徹底終止某個連接上兩個方向的數(shù)據(jù)流(即全雙工關(guān)
閉)怠李,那么它必須正確處理連接終止序列4個分節(jié)中任何一個分節(jié)丟失的情況。本例子也說
明了為什么執(zhí)行主動關(guān)閉的那一端是處于TIME_WAIT狀態(tài)的那一端:因為可能不得不重傳
最終那個ACK的就是那一端蛤克。
(2)允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝捺癞。
為理解存在TIME_WAIT狀態(tài)的第二個理由,我們假設(shè)在12.106.32.254的1500端口和
206.168.112.219的21端口之間有一個TCP連接构挤。我們關(guān)閉這個連接髓介,過一段時間后在相同
的IP地址和端口之間建立另一個連接。后一個連接稱為前一個連接的化身(incarnation)筋现,
因為它們的IP地址和端口號都相同唐础。TCP必須防止來自某個連接的老的重復(fù)分組在該連接
已終止后再現(xiàn),從而被誤解成屬于同一連接的某個新的化身夫否。
為做到這一點彻犁,TCP將不給處于TIME_WAIT狀態(tài)的連接發(fā)起新的化身。既然TIME_WAIT
狀態(tài)的持續(xù)時間是MSL的2倍凰慈,這就足以讓某個方向上的分組最多存活MSL秒即被丟棄汞幢,另
一個方向上的應(yīng)答最多存活MSL秒也被丟棄。通過實施這個規(guī)則微谓,我們就能保證每成功建立
一個TCP連接時森篷,來自該連接先前化身的老的重復(fù)分組都已在網(wǎng)絡(luò)中消逝了。
這個規(guī)則存在一個例外:
如果到達的SYN的序列號大于前一化身的結(jié)束序列號豺型,源自Berkeley的實現(xiàn)將給當(dāng)前處于TIME_WAIT狀態(tài)的連接啟動新的化身仲智。TCPv2第958~959頁對這種情況有詳細的敘述。它要求服務(wù)器執(zhí)行主動關(guān)閉姻氨,因為接收下一個SYN的那一端必須處于TIME_WAIT狀態(tài)钓辆。rsh命令具備這種能力。RFC1185[Jacobson,Braden,andZhang1990]講述了有關(guān)這種情形的一些陷阱。