為什麼一定要是三次握手,四次揮手
應用層向TCP層傳送用於網間傳輸的、用8位位元組表示的資料流,然後TCP把資料流分割槽成適當長度的報文段(通常受該計算機連線的網路的資料鏈路層的最大傳輸單元(MTU)的限制)。之後TCP把結果包傳給IP層,由它來通過網路將包傳送給接收端實體的TCP層。TCP為了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果傳送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的資料包就被假設為已丟失將會被進行重傳。TCP用一個校驗和函式來檢驗資料是否有錯誤;在傳送和接收時都要計算校驗和。
TCP是面向連線的,無論哪一方向另一方傳送資料之前,都必須先在雙方之間建立一條連線。在TCP/IP協議中,TCP協議提供可靠的連線服務,連線是通過三次握手進行初始化的。三次握手的目的是同步連線雙方的序列號和確認號並交換
TCP視窗大小資訊。
首先,來看圖:
三次握手:
- 第一次握手:建立連線。客戶端傳送連線請求報文段,將
SYN
位置為1,Sequence Number
為x;然後,客戶端進入SYN_SEND
狀態,等待伺服器的確認; - 第二次握手:伺服器收到
SYN
報文段。伺服器收到客戶端的SYN
報文段,需要對這個SYN
報文段進行確認,設定Acknowledgment Number
為x+1(Sequence Number
+1);同時,自己自己還要傳送SYN
請求資訊,將SYN
位置為1,Sequence Number
為y;伺服器端將上述所有資訊放到一個報文段(即SYN+ACK
報文段)中,一併傳送給客戶端,此時伺服器進入SYN_RECV
- 第三次握手:客戶端收到伺服器的
SYN+ACK
報文段。然後將Acknowledgment Number
設定為y+1,向伺服器傳送ACK
報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入ESTABLISHED
狀態,完成TCP三次握手。
- 第一次分手:主機1(可以使客戶端,也可以是伺服器端),設定
Sequence Number
和Acknowledgment Number
,向主機2傳送一個FIN
報文段;此時,主機1進入FIN_WAIT_1
狀態;這表示主機1沒有資料要傳送給主機2了; - 第二次分手:主機2收到了主機1傳送的
FIN
報文段,向主機1回一個ACK
報文段,Acknowledgment Number
Sequence Number
加1;主機1進入FIN_WAIT_2
狀態;主機2告訴主機1,我“同意”你的關閉請求; - 第三次分手:主機2向主機1傳送
FIN
報文段,請求關閉連線,同時主機2進入LAST_ACK
狀態; - 第四次分手:主機1收到主機2傳送的
FIN
報文段,向主機2傳送ACK
報文段,然後主機1進入TIME_WAIT
狀態;主機2收到主機1的ACK
報文段以後,就關閉連線;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連線了。
防止已過期的連線請求報文突然又傳送到伺服器,因而產生錯誤。Client發生一個請求連線報文可能因為網路延遲等原因,沒有送達到server中。但是當這個c
lient的請求報文送達到server時,如果沒有三次握手的話,server就會直接發資料可client,這樣會導致server資源的浪費。
為什麼是四次揮手呢?為了確保資料能夠完成傳輸。關閉連線時,當收到對方的FIN報文通知時,它僅僅表示對方沒有資料傳送給
你了;但不是你所有的資料都全部發送給對方了,所以你未必會馬上關閉SOCKET,也就是你可能還需要傳送一些資料
給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ACK報文和FIN報文多數情況下
都是分開發送的。
當主機1發出FIN報文段時,只是表示主機1已經沒有資料要傳送了,主機1告訴主機2,它的資料已經全部發
送完畢了;但是,這個時候主機1還是可以接受來自主機2的資料;當主機2返回ACK報文段時,表示它已經知道主機1
沒有資料傳送了,但是主機2還是可以傳送資料到主機1的;當主機2也傳送了FIN報文段時,這個時候就表示主機2也
沒有資料要傳送了,就會告訴主機1,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。