TCP協議的三次握手和四次揮手
TCP(傳輸控制協議)是一種面向連線,確保資料在端到端之間可靠傳輸的協議,面向連線指的是在傳送資料前,需要先建立一條虛擬的鏈路,然後讓資料在這條鏈路上傳輸,為了確保資料的可靠傳輸,不僅需要對發出的每個位元組進行編號確認,檢驗每一個數據包的有效性,在出現超時情況時進行重傳,還需要通過實現滑動視窗和擁塞控制機制,避免網路情況惡化而最終影響資料傳輸的極端情形,每個TCP資料包都是封裝在IP包中。每一個IP頭的後面緊接著是TCP頭,TCP報文格式如下:

螢幕快照 2018-11-24 21.29.31.png
三次握手
協議第一行的兩個埠號各佔兩個位元組,分別表示了源機器的埠號和目標機器的埠號。這個兩個埠號和IP報頭中的源IP地址和目標IP地址所組成的四元組可唯一標示一條TCP連線,由於TCP是面向連線的,因此有服務端和客戶端之分。需要服務端先在相應的埠進行監聽,準備好接受客戶端發起的建立連線請求。當客戶端發起第一個請求建立連線的TCP報時,目標機器埠就是服務端所監聽的埠號,比如代表HTTP服務的80埠,代表SSH服務的22埠,代表HTTPS服務的443埠。
TCP的FLAG位由6個bit組成,分別代表ACK,SYN,FIN,URG,PSH,RST,都以置1表示有效,我們重點關注SYN,ACK和FIN。SYN(Synchronize Sequence Numbers)用作建立連線時的同步訊號,ACK(Acknowledgement)用於對收到的資料進行確認,所確認的資料由確認序列號表示,FIN(finish)表示後面沒有資料需要傳送,通常意味著所建立的連線需要關閉了。

螢幕快照 2018-11-24 21.51.45.png
- A機器發出一個數據包並將SYN置1,表示希望建立連線,包序列號假設為x。
- B機器收到A機器傳送過來的資料包後,通過SYN得知這是一個建立連線的請求,於是傳送一個響應包並將SYN和ACK標記都置1,假設這個包的序列號是y,而確認序列號必須是x+1,表示收到了A收到了A傳送過來的SYN。在TCP中,SYN被當作資料部分的一個位元組。
-A收到B的響應包後需要進行確認,確認包中將ACK置1,並將確認序列號設定為y+1,表示收到了來自B的SYN。
這裡為什麼需要三次握手?主要有兩個目的,資訊對等和防止超時。先從資訊對等角度來看,雙方需要互相確認自己的發報能力,自己的收報能力,對方的發報能力,對方的收報能力。


連線三次握手也是防止出現請求超時導致髒連線,TTL網路報文的生存時間往往都會超過TCP請求超時時間,如果兩次握手都可以建立連線,傳輸資料並釋放連線後,第一個超時的連線請求才到達B機器的話,B機器會以為是A建立的新連線的請求,然後確認同意建立連線。因為A機器的狀態不是SYN_SENT,所以直接丟棄了B的確認資料,以致最後只是B機器單方面建立連線完畢。

螢幕快照 2018-11-24 22.30.08.png
如果是三次握手,則B機器收到連線請求後,同樣會向A機器確認連線,但因為A機器不是SYN_SENT狀態,所以會直接丟棄,B機器由於長時間沒有收到確認訊息,最終超時導致連線建立失敗,因而不會出現髒連線。
TCP 斷開連線
TCP是全雙工通訊,雙方都能作為資料的傳送和接收方,但TCP連線也會有斷開的時候,所謂相愛容易分手難,建立連線只有三次,而揮手斷開需要四次。A機器想要關閉連線,則待本方資料傳送完畢後,傳遞FIN訊號給B機器。B機器應答ACK,告訴A機器可以斷開,但是需要等B機器處理完資料,再主動給A機器傳送FIN訊號。這時,A機器處於半關閉狀態(FIN_WAIT_2),無法再發送新的資料,B機器做好連線關閉前的準備工作後,傳送FIN給A機器,此時B機器也進入半關閉狀態(CLOSE_WAIT)。A機器傳送針對B機器FIN的ACK後,進入TIME_WAIT狀態,經過2MSL(Maximum Segment Lifetime)後,沒有收到B機器傳來的報文,則確定B機器已經收到A機器最後傳送的ACK指令,此時TCP連線正式釋放。

螢幕快照 2018-11-24 22.50.50.png
四次揮手斷開連線可以用通俗的說法
男生 :我們分手吧。
女生:好,我的東西收拾完,發信息給你。(此時男生不能抱女生了)
(1小時後)
女生:我收拾好了,分手吧。(此時女生不能抱男生了)
男生:好的。(大家約定兩個月的過渡期,雙方才可以分別找新的物件)
- TIME_WAIT:主動要求關閉的機器表示收到對方的FIN報文,併發送方ACK報文,進入TIME_WAIT狀態,等2MSL後即可進入CLOSED狀態。如果FIN_WAIT_1狀態下,同時收到帶FIN標誌和ACK標誌的報文時,可以直接進入TIME_WAIT狀態,而無需進入FIN_WAIT_2狀態。
- CLOSE_WAIT:被動要求關閉的機器收到對方請求連線的FIN報文,在第一次ACK應答後,馬上進入CLOSE_WAIT狀態,這種狀態其實表示在等待關閉,並且通知應用程式傳送剩餘的資料,處理現場資訊。關閉相關資源。
- 2MSL是報文在網路中生存的最長時間,超過閥值便將報文丟棄。