本文是對小林的圖解網路的總結
TCP簡介
TCP作為一個傳輸層協議,是一個面向連接的位元組流,為應用層提供端到端的傳輸服務,和UDP不同的是,TCP提供的是可靠的面向連接傳輸服務,并且提供了流量控制等功能,
UDP提供的是無連接的不可靠服務,
TCP提供了全雙工的通信方式,
TCP頭部
首先說下TCP的頭部,TCP頭部是實作TCP協議的重要部分,

如上圖所示,TCP頭部主要包括以下資訊:
1、源埠號 (16位):
資料包的發送方埠
2、目標埠號 (16位)
資料包的接收方埠
3、序列號 seq(32位)
在請求連接的時候作業系統會分配一個32位的數作為序列號,用來標識一個資料包在發送中的位置,
TCP為應用層資料中的每個位元組都分配了一個seq號,TCP就是利用seq來實作的可靠傳輸,
TCP中的seq指的是TCP資料包中應用層資料的第一個位元組對應的序列號,
4、確認應答號 ack(32位)
表示發送端中seq在ack之前的所有位元組都已經被接收方接收了,接收方下一個希望接收的seq是ack,
5、 4個主要標識位
1、SYN
SYN = 1,代表這個資料包是客戶端和服務器之間連接資料包,
2、ACK
ACK = 1,代表這個資料包是一個答復包,用于確認收到的資料包,
3、FIN
FIN = 1,說明這是一個單方面結束連接的資料包
4、RST
RST = 1,說明TCP連接出現例外強制斷開連接,
TCP三次握手

TCP是一個面向連接的傳輸服務,在傳輸之前,需要先建立連接,
在握手之前,服務器必須開啟,并且監聽某個埠,
然后客戶端開始向服務器發送連接請求,
第一次握手

第一次握手是由客戶端向服務器發送的SYN資料包,
SYN資料包的頭部有以下特點:
1、SYN標志位
SYN標志位為1,標志著客戶端想要和服務器建立連接,
2、序列號 seq
客戶端初始化一個數作為序列號 x ,序列號標識著資料包在客戶端中發送的所有資料包中的位置,
SYN資料包不包含任何應用層資料,
客戶端發送完SYN資料包后,客戶端就處于SYN-SENT狀態,
第二次握手
第二次握手是服務器在接收到客戶端的SYN資料包后發送給客戶端的回應資料包,

第二次握手的資料包有以下特點:
1、seq
服務器也會初始化一個數作為seq = y,序列號代表著資料包在服務器在這個連接中發送的所有資料包的位置,
2、SYN標志位
SYN = 1,標志著是服務器對于客戶端建立連接的回應資料包,
3、ACK標志位
ACK = 1,標志著有一個資料包被接收了,到底是對哪個資料包的確認,資料包的序列號資訊存盤在ack欄位中,
4、ack = x + 1
ack欄位存盤的是確認回答的資料包的序列號x+1,代表著這個序列號小于x+1 的資料包已經被接收了,
當服務器接收到客戶端的SYN資料包后,會回傳一個SYN資料包,
服務器首先初始化一個數作為SYN的序列號seq : y,然后將SYN標志位和ACK標志位設為1,接著將 確認應答號ack設定為x+1,
然后將SYN資料包發送給客戶端,服務器SYN包仍然不攜帶應用層資料,
發送完SYN資料包后,服務器進入SEND-RCVD狀態,
具體的做法就是服務器中每個埠對應的有一個半連接佇列,會將對應的ack、客戶端ip地址、埠號等封裝成節點加入到半連接佇列中
SYN攻擊就是利用半連接佇列來做手腳的,SYN攻擊就是利用不同的ip地址來發送SYN包,讓其不斷進入服務器的半連接佇列,讓半連接佇列占滿,不能為正常用戶作業,
第三次握手

客戶端收到服務器的SYN資料包后,會發送一個資料包來應答,
資料包有以下特點:
1、ACK標志位
ACK = 1,標志著是對服務器SYN資料包的確認回答,
2、ack = y + 1
ack欄位存盤的是y+1,表示序列號小于y+1的資料包已經被接收了,
3、seq = x + 1
序列號為x+1,
客戶端在第三次握手的時候,就可以攜帶應用層資料了,在發送完第三次握手資料包后,客戶端就進入ESTABLISH狀態,
當服務器接收到客戶端的第三次握手資料包后,也會進入ESTABLISH狀態,
當發送完三次握手資料包后,服務器和客戶端都進入了ESTABLISH狀態,也就代表雙方正式建立了連接,
為什么需要三次握手而不是兩次或者四次
兩次握手出現的問題:
如果是兩次握手的話,當服務器收到客戶端發來的連接請求后,馬上就要為客戶端初始化記憶體,建立連接, 當出現以下例外情況的話,會造成資源浪費,
1、防止出現歷史連接
TCP有超時重傳機制,就是當一個資料報發送完之后,如果超過一段時間沒有接收到對應的確認應答資料包,就會重新發送一次,
我們假設這樣的情況,客戶端第一次發送了一個SYN資料包1,seq為1,選擇了一個耗費時間比較長的路由,導致過了超時時間還沒有發送到服務器,這個時候客戶端會重新發送一個SYN資料包2,seq為2,就是在SYN資料包2發送程序中,之前的SYN資料包1到達了服務器,這時服務器會發送一個SYN確認包3,對應的ack = 2,當客戶端接收到SYN確認包3的時候,會比較ack和當前seq是否一樣,這時客戶端由于超時,已經發送了一個SYN資料包2,客戶端中的seq已經增加到了3,不等于SYN確認包3中的ack 2,所以TCP會判定這是一個歷史連接,就會發送一個RST標志位為1,seq = 2的資料包,RST的做法是將歷史連接對應的節點從服務器中的半連接佇列中移除,
如果是兩次握手的話,對于失效連接是無法處理的,沒有辦法發送RST資料包了,
2、避免資源浪費
我們再假設這一種情況,也是資料包超時了,但是這時客戶端沒有重新發送,而是關閉了,當資料包傳入到服務器的時候,服務器會為其創建連接,但是這時客戶端已經關閉了,這就白白浪費了服務器的資源,
服務器中同一個埠的多個socket利用客戶端IP和客戶端埠號來唯一標識一個socket,
因為三次握手就可以滿足建立連接的條件了,所以不需要四次握手了,
四次揮手

TCP的建立和釋放都是由客戶端發起的,
1、第一次揮手
由客戶端發起斷開請求,斷開的是客戶端向服務器寫資料的方向連接,服務器還是能繼續向客戶端寫入資料的,FIN資料包中有以下特點:
FIN標志位
FIN=1,表示這是一個斷開連接的資料包
seq = p
發送完FIN資料包后,客戶端進入FIN_WAIT_1狀態,
2、第二次揮手
當服務器接收到客戶端的FIN資料包后,會回傳確認應答包,資料包有以下特點:
ACK標志位
ack = 1,標志著是確認應答包
ack
ack = p + 1,表示序列號為finClientSeq的資料包已經被接收
seq = a
第二次揮手后,服務器進入CLOSED_WAIT狀態
第三次揮手
第三次揮手是服務器向客戶端釋放連接發送的FIN資料包,有以下特點
1、FIN標志位 = 1
2、seq = q
發送完之后,服務器進入LAST_ACK,表示這時服務端進入最后的應答狀態,等待客戶端的確認回答,
第四次揮手
第四次揮手是客戶端向服務器發送的資料包,有以下特點:
1、ACK標志位 = 1
2、ack = q+1
3、seq = b
發送完之后,客戶端進入TIME_WAIT狀態
如果服務器接收到客戶端發來的資料包就會進入CLOSED狀態,
客戶端在等待2MSL后,也會進入CLOSED狀態,
為什么四次揮手
TCP是一個全雙工通信協議,客戶端可以向服務器發送資料,服務器也能向客戶端發送資料,
當客戶端斷開連接的時候,申請斷開的是客戶端向服務器發送資料的通道,當客戶端向服務器發送資料的通道關閉之后,客戶端還不能退出,因為客戶端還可能有資料要收取,
這個時候服務器可能還有資料還未發送完給客戶端,服務器向客戶端發送資料的通道還不能關閉,等待服務器發送資料完畢之后,才會發送FIN資料包,并且要等待客戶端的回應,因為FIN資料包可能會失效,所以客戶端還需要再次向服務器發送ACK確認應答包,當服務器收到客戶端的ACK時,才會真正關閉,
這就需要四次揮手,
客戶端為什么要等待2MSL
MSL指的是 Maxium Segement Lifetime,報文最大生存時間,當客戶端收到FIN包后,會等待2MSL時間,如果在2MSL時間內,沒有再次收到FIN包就會關閉客戶端,
因為害怕服務器沒有接收到客戶端發來的ACK包,當服務器過了超時時間沒有接收到ACK包的話,服務器會重新發送FIN包,客戶端會重新發送ACK包,然后將等待時間重新初始化為2MSL,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/299158.html
標籤:其他
