TCP
TCP,Transmission Control Protocol 傳輸控制協議,是一種面向連接的、可靠的、基于位元組流的傳輸層通信協議,通俗來講,TCP就是雙方通信的一個規范標準,負責對資料的傳輸進行一定的控制,TCP 報文格式如下:

現對其中的結構做個簡單介紹
-
源埠號就是指本地埠,目的埠號就是遠程埠
-
序號,也稱序列號(Sequence Number),用于 TCP 通信程序中某一傳輸方向上位元組流的每個位元組的編號,以防止亂序問題,簡單來說,就是在傳輸程序中用序列號來標記自己的位置,保證資料能按序傳輸
-
確認序號,也稱確認序列號(Acknowledgment Numbe),是接收確認端所期望收到的下一序列號,確認序號應當是上次已成功收到資料位元組序號加 1,只有當標志位中的 ACK 標志為 1 時該確認序列號的欄位才有效,主要用來解決不丟包的問題
-
標志位,TCP Flag,TCP 首部中有 6 個標志位元,它們中的多個可同時被設定為 1,主要是用于操控 TCP 的狀態機,依次為 URG,ACK,PSH,RST,SYN,FIN
-
ACK
表示應答域有效,這個標識可以理解為發送端發送資料到接收端,發送的時候 ACK 為 0,標識接收端還未應答,一旦接收端接收資料之后,就將 ACK 置為 1,發送端接收到之后,就知道了接收端已經接收了資料
-
SYN
表示同步序列號,用來建立 TCP 連接,SYN 標志位和 ACK 標志位搭配使用,當連接請求的時候,SYN = 1,ACK = 0;連接被回應的時候,SYN = 1,ACK = 1;這個標志的資料包經常被用來進行埠掃描,掃描者發送一個只有 SYN 的資料包,如果對方主機回應了一個資料包回來 ,就表明這臺主機存在這個埠
-
FIN
表示發送端已經達到資料末尾,也就是說雙方的資料傳送完成,沒有資料可以傳送了,發送 FIN 標志位的 TCP 資料包后,連接將被斷開,這個標志的資料包也經常被用于進行埠掃描
-
-
視窗大小(Window Size),也稱為滑動視窗大小,用來進行流量控制
TCP 三次握手
TCP 三次握手,即建立 TCP 連接,需要客戶端和服務端總共發送 3 個包以確認連接的建立,在 Socket 編程中,這一程序由客戶端執行 connect 來觸發,TCP 握手的目的有三個:確認雙方的接收與發送能力是否正常;初始化序列號,為后面的可靠傳送做準備;進行數字證書的驗證以及加密密鑰的生成

- 第一次握手:客戶端發送請求報文將 SYN = 1 同步序列號和初始化序列號 seq = J 發送給服務端,發送完之后客戶端處于發送等待狀態
- 第二次握手:服務端受到 SYN 請求報文之后,如果同意連接,會以自己的同步序列號 SYN = 1、初始化序列號 seq = K 和確認序列號(期望下次收到的資料包)ack = J + 1 以及確認號 ACK = 1 報文作為應答,此時服務器為確認接收狀態
- 第三次握手:客戶端接收到服務端的 SYN + ACK 之后,知道可以發送下一序列的資料包了,然后發送同步序列號 ack = K + 1 和資料包的序列號 seq = J + 1 以及確認號 ACK = 1 確認包作為應答,客戶端轉為確認連接狀態
為什么是三次握手?
為什么是三次握手,而不是一次、二次呢?因為有可能出現這種情況:客戶端發送了一個連接請求,但出現網路延遲,導致客戶端沒有及時收到服務端的回應,就會認為本次請求失效,而這時原本延遲的請求又來到服務端,服務端確認并保持等待狀態,但實際上此時客戶端并沒有與服務端連接的意思,這就會導致服務器一直處于等待狀態,造成資源浪費
TCP 四次揮手
TCP 四次揮手,即終止 TCP 連接,需要客戶端和服務端總共發送 4 個包以確認連接的斷開,在 Socket 編程中,這一程序由客戶端或服務端任一方執行 close 來觸發

- 第一次分手:第一次分手無論是客戶端還是服務端都可以發起,因為 TCP 是全雙工的,假如客戶端發送的資料已經發送完畢,發送 FIN = 1 告訴服務端,客戶端所有資料已經全發完了,服務端可以關閉接收了,但如果服務端還有資料要發給客戶端,客戶端照樣可以接收的,此時客戶端處于 FIN_WAIT_1 等待關閉狀態
- 第二次分手:服務端接收到客戶端的釋放請求連接之后,知道客戶端沒有資料要發給自己了,然后服務端發送 ACK = 1 告訴客戶端已經收到發給自己的資訊,此時服務端處于 CLOSE_WAIT 等待關閉狀態
- 第三次分手:此時服務端已經沒有資料向客戶端發送了,然后發送一個 FIN = 1,用于告訴客戶端,服務端的所有資料發送完畢,客戶端可以關閉接收資料連接了,此時服務端狀態處于 LAST_ACK 確認關閉狀態
- 第四次分手:此時如果客戶端收到了服務端發送完的資訊之后,就發送 ACK = 1,告訴服務端,客戶端已經收到了服務端的資訊,服務端處于 CLOSED 狀態,四次揮手全部完成
為什么是四次揮手?
為什么是四次揮手呢?因為關閉連接時,己方收到對方的 FIN 報文,僅僅表示對方不再向自己發送資料,但還能接受資料,己方可能還有資料要發送給對方,所以不能向三次握手一樣直接把 ACK 和 SYN 放一起發送,而是先發送 ACK,直到沒有資料要發送了,才是 FIN 確認關閉連接
為什么 TIME_WAIT 狀態需要經過 2MSL 才能回傳到 CLOSE 狀態?
假設出現各種網路原因,使得服務端沒有接收到客戶端最后回復的 ACK,這時服務端就會重新發送 FIN,如果沒有 2MSL 的延遲,那客戶端回復 ACK 后就立即處于 close 狀態,自然也無法接收到服務端再次發送的 FIN,最后服務端會認為出現連接錯誤問題并報告給上層,這種情況雖然不至于導致資料丟失,但不符合 TCP 是可靠連接的要求
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/167657.html
標籤:其他
上一篇:冒泡、選擇、插入排序
下一篇:Eclipse部署虛擬專案目錄
