深入理解TCP/IP协议-TCP建立与终止连接
轉載自??深入理解TCP/IP協議-TCP建立與終止連接
?
一、引言
??TCP 是一個面向連接的協議。無論哪一方向另一方發送數據之前,都必須先在雙方之間建立一條連接。連接創建與終止的狀態變化圖如下:
?
二、三次握手建立連接
過程如下:
-  客戶端發送一個 SYN 數據包指明客戶端打算連接服務器的端口,初始化序號(ISN)為 m。 
-  服務器發回包含服務器的 ISN 作為應答(值為 n)。同時,將確認序號設置成客戶端 ISN+1(m+1)來作為對客戶端 SYN 的確認。 
-  客戶端發送一個 ACK 數據包,ack=n+1, 作為對服務器的 SYN 的確認。 
1. 為什么是三次握手,而不是兩次
??網絡是不可靠的,數據包是可能丟失的。假設沒有第三次確認,客戶端向服務端發送了 SYN,請求建立連接。由于延遲,服務端沒有及時收到這個包。于是客戶端重新發送一個 SYN 包。回憶一下介紹 TCP 首部時提到的序列號,這兩個包的序列號顯然是相同的。假設服務端接收到了第二個 SYN 包,建立了通信,一段時間后通信結束,連接被關閉。這時候最初被發送的 SYN 包剛剛抵達服務端,服務端又會發送一次 ACK 確認。由于兩次握手就建立了連接,此時的服務端就會建立一個新的連接,然而客戶端覺得自己并沒有請求建立連接,所以就不會向服務端發送數據。從而導致服務端建立了一個空的連接,白白浪費資源。
 ??TCP是雙通道,需要雙向確定。只有兩次握手,客戶端知道了服務器收到了,服務器不知道客戶端收到了,聯想打電話。通訊系統中的占拜庭將軍問題。
2. 最大報文段長度
??最大報文段長度(MSS)表示 TCP 傳往另一端的最大塊數據的長度。當一個連接建立時,連接的雙方都要通告各自的 MSS。在三次握手的時候 SYN 的 TCP 首部中的可選字段確定。以太網的默認長度為 1460。
?
三、四次握手關閉連接(正常狀態)
??建立一個連接需要三次握手,而終止一個連接要經過 4 次握手。這由 TCP 的半關閉 (half-close) 造成的。一個 TCP 連接是全雙工(即數據在兩個方向上能同時傳遞),因此每個方向必須單獨地進行關閉。
-  主動方想要關閉連接,發送 FIN 包給被動方,序號為 m 
-  被動方接收到主動方發送的 FIN 包,知道了對方要關閉連接,發送 ACK 確認包,序號 m+1。主動方連接關閉。 
-  等待片刻(處于半關閉狀態),在此期間(finwait2,closewait)。被動方發送最后的數據,主動方接收最后的數據。 
-  被動方確認要關閉連接,發送 FIN 包。序號 n。 
-  主動方等待片刻(接收網絡中,還未到達的數據包),發送 ACK 確認包。序號 n+1。到此連接關閉。 
1.TCP 的半關閉狀態
??TCP 提供了連接的一端在結束它的發送后還能接收來自另一端數據的能力。如主動方處于 fin_wait2 狀態。
2.TIME_WAIT 狀態
??TIMEWAIT 狀態也稱為 2MSL 等待狀態。每個具體 TCP 實現必須選擇一個報文段最大生存時間 MSL( Maximum Segment Lifetime)。它是任何報文段被丟棄前在網絡內的最長時間。因為 TCP 報文段以 IP 數據報在網絡內傳輸,而 IP 數據報則有限制其生存時間的 TTL 字段。在實際應用中,對 I P 數據報 TTL 的限制是基于跳數,而不是定時器。 ??在處于 2MSL 等待狀態的 socket(客戶端 IP 與端口,服務器 IP 與端口) 不能再被使用。但在實際的使用中,允許一個新的連接請求到達仍處于 timewait 狀態的連接,只要新的序號大于該連接的前一個連接的最后序號。
?
四、正常狀態抓包
下面是一次完整的 tcp 建立連接,發送數據,關閉連接過程
該過程為,3 次握手建立連接,一次數據發送,4 次握手關閉連接
?
?
五、異常情況
出現異常的時候,服務器通常通過復位報文來通告,復位報文為 tcp 數據包類型設置為 rst。
1. 連接超時或到達不存在的端口 / 服務器
當服務器端沒有開或網絡問題,會出現連接超時的情況。抓包如下:
客戶端嘗試 3 三次來連接,有時候服務器端會發送 rst 數據包。
2. 異常終止一個連接
??在 TCP 通訊中。如果通訊雙方應為某種原因(如突然斷電等)關閉連接時候一方(如 A)沒有發送 fin 數據包。另一端 (如 B) 不知道對方已經關閉了連接。再次發送數據的時候,異常關閉的一方,可能會返回一個 rst 數據包。通知異常關閉。如果一方已經關閉或異常終止連接而另一方卻還不知道,我們將這樣的 TCP 連接稱為半打開 (Half Open) 的。
3. 同時打開
??兩個應用程序同時彼此執行主動打開的情況是可能的。每一方必須發送一個 SYN,且這些 SYN 必須傳遞給對方。這需要每一方使用一個對方熟知的端口作為本地端口。同時打開的狀態遷移圖不同于正常狀態的三次握手,該情況下需要進行 4 次握手。如圖:
4. 同時關閉
??我們在以前討論過一方(通常但不總是客戶方)發送第一個 FIN 執行主動關閉。雙方都執行主動關閉也是可能的,TCP 協議也允許這樣的同時關閉(simultaneous close)。在同時關閉的時候,雙方都進入 time_wait 狀態,如圖:
?
六. TCP 服務器設計
??大多數的 TCP 服務器進程是并發的。當一個新的連接請求到達服務器時,服務器接受這個請求,并調用一個新進程來處理這個新的客戶請求。
1. 接入連接請求隊列
??一個并發服務器調用一個新的進程來處理每個客戶請求,因此處于被動連接請求的服務器應該始終準備處理下一個呼入的連接請求。那正是使用并發服務器的根本原因。但仍有可能出現當服務器在創建一個新的進程時,或操作系統正忙于處理優先級更高的進程時,到達多個連接請求。當服務器正處于忙時,TCP 是如何處理這些呼入的連接請求?TCP 有這樣一個隊列來臨時存放這些連接 - 接入連接請求隊列。處理方式如下:
-  正等待連接請求的一端有一個固定長度的連接隊列,該隊列中的連接已被 TCP 接受(即三次握手已經完成),但還沒有被應用層所接受。注意區分 TCP 接受一個連接是將其放入這個隊列,而應用層接受連接是將其從該隊列中移出。 
-  應用層將指明該隊列的最大長度,這個值通常稱為積壓值 (backlog)。 
-  當一個連接請求(SYN)到達時, TCP 使用一個算法,根據當前連接隊列中的連接數來確定是否接收這個連接。積壓值說明的是 TCP 監聽的端口已被 TCP 接受而等待應用層接受的最大連接數。 
-  如果對于新的連接請求,該 TCP 監聽的端口的連接隊列中還有空間,TCP 模塊將對 SYN 進行確認并完成連接的建立。此時,應用層不一定知道該新的連接,如果對方發送數據,這些數據將放入緩沖隊列中。 
-  如果對于新的連接請求,連接隊列中已沒有空間,TCP 將不理會收到的 SYN。也不發回任何報文段(即不發回 RST)。如果應用層不能及時接受已被 TCP 接受的連接,這些連接可能占滿整個連接隊列,客戶的主動打開最終將超時。 
總結
以上是生活随笔為你收集整理的深入理解TCP/IP协议-TCP建立与终止连接的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 9个最佳游戏团队标志"如何免费获得[20
- 下一篇: 在 Java 中初始化 List 的五种
