TCP概述
網絡分為IOS七層協定:實體層、資料鍊路層、網絡層、傳輸層、會話層、表現層、應用層
TCP協定屬于傳輸層的協定
TCP資料包結構圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiETPwJWZ3ZCMwcTP39zZwpmLuJkbhVXS65UerR0TxEERPVDMp5keBpWT3lkeNdXRE5EeNRUT4lERNlHM55UNVRkTwcGVNZXTE1EeJRUT5hTeOVTVE5EMnRVT2NmMiNnSywEd5ITW110MaZHetlVdO1GT3lERNl3YXJGc5kHT20ESjBjUIF2Lc12bj5SYphXa5VWen5WY35iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.jpg)
在進行握手時,就依賴着結構中的序号和确認号
TCP中的辨別符
SYN:同步标志
同步序列編号( Synchronize Sequence Numbers
)欄有效。該标志僅在三次握手建立TCP連接配接時有效。它提示TCP連接配接的服務端檢查序列編号,該序列編号為TCP連接配接初始端(一般是用戶端)的初始序列編号。在這裡,可以把TCP序列編号看作是一個範圍從0到4,294,967,295的32位計數器。通過TCP連接配接交換的資料中每一個位元組都經過序列編号。在TCP報頭中的序列編号欄包括了TCP分段中第一個位元組的序列編号
ACK:确認标志
确認編号( Acknowledgement Number
)欄有效。大多數情況下該标志位是置位的。TCP報頭内的确認編号欄内包含的确認編号(w+1,Figure-1)為下一個預期的序列編号,同時提示遠端系統已經成功接收所有資料
URG:緊急标志
緊急( The urgent pointer
) 标志有效,緊急标志置位
FIN:結束标志
帶有該标志置位的資料包用來結束一個TCP會話,但對應端口仍處于開放狀态,準備接收後續資料
三次握手
Three-way Handshake
三次握手
一個虛拟連接配接的建立是通過三次握手實作的
示意圖
三次握手流程
- B的TCP伺服器程序先建立傳輸子產品TCB,準備接受客戶程序的連接配接請求。然後伺服器程序就處于
(收聽)狀态,等待客戶的連接配接請求LISTEN
- 第一次握手:A的TCP客戶程序也是首先建立傳輸控制子產品TCB,然後向B發出連接配接請求封包段,此時首部中的同部位
,同時選擇一個初始序号SYN = 1
(這個指令的意思就是告訴B客戶機自己的序号是多少,要接着這個序号發送資料報)。TCP規定,SYN封包段(即seq = x
的封包段)不能攜帶資料,但是要消耗一個需要。此時TCP客戶程序進入SYN = 1
(同步已發送)狀态SYN-SENT
- 第二次握手:B收到連續請求封包段後,如同意建立連接配接,則向A發送确認。在确認封包段中應把
位和SYN
位都置為1,确認号是ACK
,同時自己也為自己選擇一個初始序号ack = x + 1
。(注意:這個封包段也不能攜帶資料,但同樣需要消耗掉一個序号)。這時TCP伺服器程序進入seq = y
(同步收到)狀态SYN-REVD
- 第三次握手:TCP客戶程序收到B的确認後,還要向B給出确認。确認封包段的ACK置1,确認号
,而自己的序号ack = y + 1
。TCP的标準規定,ACK封包段可以攜帶資料。但如果不攜帶資料則不消耗序号,在這種情況下,下一個資料封包段的序号仍是seq = x + 1
。這時,TCP連接配接建立,A進入seq = x + 1
(已建立連接配接)狀态,當B收到A的确認消息後,也進入ESTABLISHED
狀态ESTABLISHED
注:最後一次握手在預設不攜帶資料的情況下,由于SYN不是1,是不消耗序列号的。是以三次握手結束後,用戶端下一個發送的封包中依舊是
seq
x + 1
為什麼需要三次握手,而非兩次?
- 為了實作可靠資料傳輸, TCP 協定的通信雙方, 都必須維護一個序列号, 以辨別發送出去的資料包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方互相告知序列号起始值, 并确認對方已經收到了序列号起始值的必經步驟
- 如果隻是兩次握手, 至多隻有連接配接發起方的起始序列号能被确認, 另一方選擇的序列号則得不到确認
四次揮手
一個虛拟連接配接的斷開是通過四次揮手實作的
示意圖:
四次揮手流程:
- 第一次揮手:A資料傳輸關閉,需要斷開連接配接,A應用程序向其TCP發出連接配接釋放封包段(
),并停止在發送資料,主動關閉TCP連接配接,進入FIN-WAIT-1狀态,等待B的确認FIN = 1, seq = u
- 第二次揮手:B收到連接配接釋放封包後即發出确認封包段(
,确認号ACK = 1
,序列号ack = u + 1
),B進入CLOSE-WAIT關閉等待狀态,此時的TCP處于半關閉狀态,A到B的連接配接釋放。而A收到B的确認後,進入FIN-WAIT-2狀态,等待B發出的連接配接釋放封包段seq = v
- 第三次揮手:當B資料傳輸完畢,B發出連接配接釋放封包段(
,FIN = 1
,序号ACK = 1
,确認号seq = u + 1
),B進入LAST-ACK(最後确認)狀态,等待A的最後确認ack = u + 1
- 第四次揮手:A收到B的連接配接釋放封包段後,對此發出确認封包段(
,ACK = 1
,seq = u + 1
),A進入TIME-WAIT(時間等待)狀态,此時TCP未釋放掉,需要經過時間等待計時器設定的時間2MSL後,A才進入CLOSE狀态ack = w + 1
為什麼A在TIME-WAIT狀态必須等待2MSL(最大封包生存時間)的時間?
為了保證A發送的最後一個ACK封包段能夠到達B,保證A、B正常進入CLOSED狀态
這個ACK封包段有可能丢失,使得處于LAST-ACK狀态的B收不到對已發送的FIN+ACK封包段的确認,B逾時重傳FIN+ACK封包段,A能2MSL時間内收到這個重傳的FIN+ACK封包段,接着A重傳一次确認,同時重新開機2MSL計數器,2MSL時間後A和B進入CLOSE狀态,如果A在TIME-WAIT狀态時接收到B的FIN+ACK封包段之後向B發出确認封包段,而不再确認B是否收到立即進入CLOSED狀态,如若B并沒有正常收到A 的确認封包段,則B無法正正常進入到CLOSED狀态