程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 【轉】TCP的SEQ和ACK的生成

【轉】TCP的SEQ和ACK的生成

編輯:C++入門知識

TCP序列號和確認號詳解

完整的PDF下載:

在網絡分析中,讀懂TCP序列號和確認號在的變化趨勢,可以幫助我們學習TCP協議以及排查通訊故障,如通過查看序列號和確認號可以確定數據傳輸是否亂序。但我在查閱了當前很多資料後發現,它們大多只簡單介紹了TCP通訊的過程,並沒有對序列號和確認號進行詳細介紹,結合實例的講解就更沒有了。近段時間由於工作的原因,需要對TCP的序列號和確認號進行深入學習,下面便是我學習後的一些知識點總結,希望對TCP序列號和確認號感興趣的朋友有一定幫助。

1.   序列號和確認號的簡介及作用

TCP協議工作在OSI的傳輸層,是一種可靠的面向連接的數據流協議,TCP之所以可靠,是因為它保證了傳送數據包的順序。順序是用一個序列號來保證的。響應包內也包括一個序列號,表示接收方准備好這個序列號的包。在TCP傳送一個數據包時,它會把這個數據包放入重發隊列中,同時啟動計時器,如果收到了關於這個包的確認信息,便將此數據包從隊列中刪除,如果在計時器超時的時候仍然沒有收到確認信息,則需要重新發送該數據包。另外,TCP通過數據分段中的序列號來保證所有傳輸的數據可以按照正常的順序進行重組,從而保障數據傳輸的完整。

2.   TCP的通訊過程

在TCP通訊中主要有連接的建立、數據的傳輸、連接的關閉三個過程!每個過程完成不同的工作,而且序列號和確認號在每個過程中的變化都是不同的。

2.1 TCP建立連接

TCP建立連接,也就是我們常說的三次握手,它需要三步完成。在TCP的三次握手中,發送第一個SYN的一端執行的是主動打開。而接收這個SYN並發回下一個SYN的另一端執行的是被動打開。

這裡以客戶端向服務器發起連接來說明。

1)   第1步:客戶端向服務器發送一個同步數據包請求建立連接,該數據包中,初始序列號(ISN)是客戶端隨機產生的一個值,確認號是0;

2)   第2步:服務器收到這個同步請求數據包後,會對客戶端進行一個同步確認。這個數據包中,序列號(ISN)是服務器隨機產生的一個值,確認號是客戶端的初始序列號+1;

3)   第3步:客戶端收到這個同步確認數據包後,再對服務器進行一個確認。該數據包中,序列號是上一個同步請求數據包中的確認號值,確認號是服務器的初始序列號+1。

注意:因為一個SYN將占用一個序號,所以要加1。

初始序列號(ISN)隨時間而變化的,而且不同的操作系統也會有不同的實現方式,所以每個連接的初始序列號是不同的。TCP連接兩端會在建立連接時,交互一些信息,如窗口大小、MSS等,以便為接著的數據傳輸做准備。

RFC793指出ISN可以看作是一個32bit的計數器,每4ms加1,這樣選擇序號的目的在於防止在網絡中被延遲的分組在以後被重復傳輸,而導致某個連接的一端對它作錯誤的判斷。

2.2 TCP傳輸數據

在TCP建立連接後,就可以開始傳輸數據了。TCP工作在全雙工模式,它可以同時進行雙向數據傳輸。這裡為了簡化,我們只談服務器向客戶端發送數據的情況,而客戶端向服務器發送數據的原理和它是類似的,這裡便不重復說明。
服務器向客戶端發送一個數據包後,客戶端收到這個數據包後,會向服務器發送一個確認數據包。

傳輸數據的簡要過程如下:

1)   發送數據:服務器向客戶端發送一個帶有數據的數據包,該數據包中的序列號和確認號與建立連接第三步的數據包中的序列號和確認號相同;

2)   確認收到:客戶端收到該數據包,向服務器發送一個確認數據包,該數據包中,序列號是為上一個數據包中的確認號值,而確認號為服務器發送的上一個數據包中的序列號+所該數據包中所帶數據的大小。
數據分段中的序列號可以保證所有傳輸的數據按照正常的次序進行重組,而且通過確認保證數據傳輸的完整性。

2.3 TCP關閉連接

前面我們提到,建立一個連接需要3個步驟,但是關閉一個連接需要經過4個步驟。因為TCP連接是全雙工的工作模式,所以每個方向上需要單獨關閉。在TCP關閉連接時,首先關閉的一方(即發送第一個終止數據包的)將執行主動關閉,而另一方(收到這個終止數據包的)再執行被動關閉。

關閉連接的4個步驟如下: 

1)   第1步:服務器完成它的數據發送任務後,會主動向客戶端發送一個終止數據包,以關閉在這個方向上的TCP連接。該數據包中,序列號為客戶端發送的上一個數據包中的確認號值,而確認號為服務器發送的上一個數據包中的序列號+該數據包所帶的數據的大小;

2)   第2步:客戶端收到服務器發送的終止數據包後,將對服務器發送確認信息,以關閉該方向上的TCP連接。這時的數據包中,序列號為第1步中的確認號值,而確認號為第1步的數據包中的序列號+1;

3)   第3步:同理,客戶端完成它的數據發送任務後,就也會向服務器發送一個終止數據包,以關閉在這個方向上的TCP連接,該數據包中,序列號為服務器發送的上一個數據包中的確認號值,而確認號為客戶端發送的上一個數據包中的序列號+該數據包所帶數據的大小;

4)   第4步:服務器收到客戶端發送的終止數據包後,將對客戶端發送確認信息,以關閉該方向上的TCP連接。這時在數據包中,序列號為第3步中的確認號值,而確認號為第3步數據包中的序列號+1;

注意:因為FIN和SYN一樣,也要占一個序號。理論上服務器在TCP連接關閉時發送的終止數據包中,只有終止位是置1,然後客戶端進行確認。但是在實際的TCP實現中,在終止數據包中,確認位和終止位是同時置為1的,確認位置為1表示對最後一次傳輸的數據進行確認,終止位置為1表示關閉該方向的TCP連接。

3.   實際數據包分析

結合上面的理論,下面我們訪問網頁來捕獲數據包,通過實際的數據包來驗證序列號和確認號在TCP連接建立、傳輸數據以及關閉連接時的變化。

打開科來網絡分析系統,首先為減少數據干擾,在過濾器中設置只捕獲TCP協議的數據,然後開始捕獲,同時,訪問,待頁面下載完成後,停止捕獲。

此次環境中,客戶端為192.168.0.92,服務器為:222.77.187.23。

3.1 TCP建立連接

在捕獲的數據包中,首先我們來查看建立連接的三次握手信息,並且觀察數據包中序列號和確認號的變化。為了讓大家看的更加明白,我在這裡使用了“添加數據包注釋”的功能。

( 建立連接第一步)

客戶端向服務器發起一個同步請求數據包,請求連接服務器的80端口,客戶端隨機產生一個初始序列號(ISN)為2712239078,確認號為0。

注意:在實際情況中,我們訪問網站首先進行的是域名解析,這裡我們設置了過濾器所以沒有捕獲到DNS數據包。 

( 建立連接第二步)

服務器收到客戶的同步請求數據包後,並向客戶端發送一個同步確認數據。這個數據包中,服務器隨機產生一個初始序列號(1288781508),同時,將客戶端發送的初始序列號(ISN)加1(2712239078+1=2712239079)以作為確認號發回給客戶段進行確認。


( 建立連接第三步)

客戶端收到這個同步確認數據包後,再次對服務器進行一次確認。在這個數據包中,序列號為上一個數據包的確認號(2712239079),確認號為服務器的初始序列號(ISN)加1(1288781508+1=1288781509),以對服務器的同步確認數據包進行確認,這樣TCP連接就建立了。

3.2 TCP傳輸數據

TCP連接建立後,馬上就開始傳輸數據,這裡客戶端主動向服務器發送一個GET請求,來提交自己的請求信息。

(   傳輸數據)

圖4中的是客戶端向服務器發送的GET請求據數據包,我們注意看序列號和確認號的值!該數據包中,序列號為2712239079,確認號為1288781509,這和三次握手的第三步的數據包中的序列號和確認號相同。
從圖4中看出這個數據包的大小為1018字節,其中減去14字節Ethernet報頭,20字節的IP報頭,20字節的TCP報頭和4字節的FCS(1018-14-20-20-4=960),得到傳輸的數據大小為1432。我們將該數據包中的序列號加上該數據大小(即2712239079+960=2712240039),發現與“下一個序列號”的值完全吻合,也就是下一個數據包中服務器發送給客戶端的數據包中的確認號。

( 確認收到)

注意:“下一個序列號”是科來網絡分析系統為了方便用戶查找下一個連續數據包,而根據數據包序列號和確認號自動計算得出,該字段在實際數據包中是不存在的。

3.3 TCP關閉連接

在傳輸數據完成之後,TCP會關閉連接,這裡是服務器主動關閉該方向上的TCP連接。我們繼續來觀察捕獲的數據包,先來看關閉連接的第一步,這裡是服務器主動發起關閉

(   關閉連接第一步)

服務器向客戶端主動發起確認位和終止位同時置為1的數據包,確認位置1表示對最後一次傳輸的數據進行確認,終止位置1表示關閉該方向的TCP連接,關閉服務器和客戶端的TCP連接。在這個數據包中,序列號為客戶端發送的上一個數據包中所帶的確認號值(1288781777),而確認號為服務器發送的上一個數據包中的序列號+該數據包所帶的數據的大小(2712238597+1432=2712240039);

然後客戶端收到該終止數據包,會對服務器發送一個確認數據包,該數據包中,序列號為第1步中的確認號值(2712240039),而確認號為第1步的數據包中的序列號+1(1288781777+1=1288781778);
我們注意觀察序列號和確認號的變化情況。

( 關閉連接第二步)

隨後,就是來自客戶端被動發起的關閉,它與服務器主動發起的關閉同理,只不過這次是被動關閉客戶端方向上的TCP連接,我們就不重復說明。


我們根據以上對TCP的建立連接、傳輸數據和關閉連接三個過程的抓包分析,成功的驗證了前面所說的理論。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved