標籤:des cWeb style blog http color os io
轉載 TCP/IP 協議簡單分析
首先TCP和IP是兩種不同的協議,它們來七層網路模型中分別在不同的層次,IP協議是網路層的協議,TCP是更高一層的傳輸層的協議,TCP是建立在IP協議之上的,所以一般把TCP和IP連在一起說TCP/IP協議。
Windows系統的TCP協議棧的資料包預設是1460位元組大小,如果一次傳輸的資料大於這個長度,會把分割成幾個長度都不大於1460位元組的TCP資料包,每個資料包都會被賦予一個sequnce number(相當於每個資料包的順序號,憑這個接收端可以知道資料包的前後順序)
之後TCP的資料包再被包裹上一層IP的資料的頭,形成IP資料包在網上傳輸(其實最後還要包一層乙太網路資料包,網路上最終傳輸的都是乙太網路資料包)。
IP資料包到了目的地後,接收端首先把IP資料包的包頭去掉,取出TCP的包。接收端每收到一個TCP的資料包都需要返回給發送端一個ACK的資料包告訴發送端已接到此資料包,如果接收端在一定的時間內沒有收到某個資料包的ACK響應,會再次發送這個資料包,這樣就保證了資料都能被接收端接收到(網際網路上丟資料包是很正常的事,如果沒有資料包重發機制,很難保證發送的資料都能被接收端完整的收到)。
每個TCP資料包也是由包頭和實際資料群組成,包頭包含如下主要內容:
l Source port(2位元組)
發送端的連接埠號碼
l Destination port(2位元組)
接收端的連接埠號碼
TCP包頭中只包含雙方的連接埠號碼,雙方的IP地址在IP包的包頭,所以在TCP資料包的包頭中沒有IP地址。
l Sequence number(4位元組)
資料的順序號,表示當前資料包中的資料起始順序號,比如前一個資料包的SEQ為十六進位的:df d5 aa 3d ,資料包的實際資料長度為16位元組,那麼下一個資料包的SEQ就要在前一個資料包的SEQ基礎上加上16,為:df d5 aa 4d
l Acknowledgement number(4位元組)
接收到對方的某個資料包後的回應順序號。如果接收到了對方主動發送來的某個資料包,必須要返回對方一個ACK回應資料包,資料包的頭部的Acknowledgement number部分根據對方發送資料的SEQ和實際資料長度,返回SEQ + 實際資料長度,表示已經接收到這個資料包。對方收到這個回應,根據數值計算後知道這個資料包已經被對方接收。如果接收不到ACK的回應,就意味著這個資料包已經在網上被丟失,需要重新發送此資料包。
l Header length(1位元組)
表示TCP資料包的包頭長度,整個TCP資料包的長度減包頭長度就能得到TCP資料包的實際傳送的資料長度。
l Flags(1位元組)
標誌位元組,每一位都是一個標誌,以下是幾個主要標誌:
ACK – 表示資料包是個ACK回應資料包,表示接收到了對方的某個資料包,具體哪個包由包頭的Acknowledgement number部分指示。
PSH – 表示這是個有實際資料的包。
SYN – 表示這是個建立串連的資料包,通訊雙方要通訊,總是由用戶端先發送SYN資料包到服務端以建立TCP的串連。
FIN – 表示通訊結束,拆除串連的資料包。
下面描述一次TCP傳送資料的完整過程,以一個用戶端向服務端發送一些資料為例。
Figure 1.一次完整的TCP通訊的過程
1、 建立串連
TCP是連線導向的協議,用戶端和服務端要通訊就必須先建立一個串連。首先通訊雙方都有地址,就是IP地址加連接埠號碼(IP:Port)標識通訊的每一端,用戶端的IP:Port跟伺服器IP:Port之間就構成一個socket通訊端。所謂建立串連就是在用戶端的IP:Port跟伺服器IP:Port之間建立一個通道,初始化一些通訊的基礎設定,以便以後的資料通訊的正常進行。
1.1. 用戶端發送SYN
總是用戶端發起串連,首先用戶端發送SYN資料包到服務端以建立TCP串連。
SYN資料包只有TCP包頭,沒有實際資料。
Flags標誌位元組的SYN位置位,表示是SYN資料包。
Sequence number由用戶端隨機產生一個4位元組的資料,作為本次串連通訊用戶端資料的起始順序號,以後用戶端發往服務端的資料包的Sequence number都在此基礎上加上每次傳送的實際資料長度依次相加遞增,這樣根據每個資料包的Sequence number就能判斷出資料包的前後順序,以便接收方根據資料包的順序拼接資料包。
1.2. 服務端回應ACK、SYN
服務端收到用戶端的SYN後,首先要發送一個ACK資料包給用戶端表示收到了這個資料包。
資料包的Flags標誌位元組的ACK置位,表示是ACK回應資料包。
Acknowledgement number 設定為接收到的資料包的 SEQ + 資料包實際長度,因為接收到的SYN的實際資料長度為0,但是TCP協議認為實際長度為0的主動發送的資料長度為1,SYN是用戶端主動發送的資料包,所以服務端把Acknowledgement number 設定為接收到的資料包的 SEQ + 1。
TCP通訊可以是雙向的,一旦建立了串連,服務端也可以向用戶端發送資料。
所以服務端也會向用戶端發送一個SYN包,資料包的Flags標誌位元組的SYN置位,表示是SYN資料包,同時隨機產生一個4位元組的資料,作為本次串連通訊服務端資料的起始順序號Sequence number。
實際中,服務端把這兩個資料包合并為一個資料包,SYN和ACK都是置位,Sequence number和Acknowledgement number也同時設定,作為一個資料包發送回用戶端。
1.3. 用戶端回應ACK
用戶端收到服務端的SYN資料包後,需要回應一個ACK資料包,表示接收到此資料包。同樣ACK資料包的Acknowledgement number 設定為接收到的資料包的 SEQ + 1(SYN、ACK資料包的實際資料長度也是0)。
2、 相互收發資料
通訊雙方建立了串連後,就可以相互進行資料包的傳送。
發送資料的一端,把資料包的Flags標準位元組的PSH置位,表示是有實際資料的資料包。
Sequence number置為前一次的資料包的Sequence number加上前一次資料包的長度。
如果資料包還兼做ACK包,則把ACK置位,同時設定好Acknowledgement number把資料包發送到對方。
接收方收到對方主動發送的資料資料包後,一定要回複ACK資料包,如果同時有資料發往對方,可以把實際資料包跟ACK資料包合在一起發送。
在拆除串連之前,通訊雙方可以一直相互發送接收資料,資料的順序都建立在各自的Sequence number基礎上。
圖1中,藍色部分的資料通訊就表示這一階段。
3、 拆除串連
雙方資料交換完畢,需要拆除串連,結束通訊。
3.1. 用戶端發送FIN
通訊的一方向另一方發送FIN資料包表示要結束通訊,拆除串連。
用戶端把資料包的Flags標準位元組的FIN置位,表示是通訊結束資料包。
3.2. 服務端返回ACK,FIN
服務端收到用戶端的FIN資料包後,先回應一個ACK資料包,然後也發送一個FIN資料包,還是服務端也結束通訊。
3.3. 用戶端回應ACK
用戶端回應ACK表示接收到服務端的FIN資料,雙方通訊結束。