利用tcpdump抓包工具監控TCP連接的三次握手和斷開連接的四次揮手


TCP傳輸控制協議是面向連接的可靠的傳輸層協議,在進行數據傳輸之前,需要在傳輸數據的兩端(客戶端和服務器端)創建一個連接,這個連接由一對插口地址唯一標識,即是在IP報文首部的源IP地址、目的IP地址,以及TCP數據報首部的源端口地址和目的端口地址。TCP首部結構如下:




其中在TCP連接和斷開連接過程中的關鍵部分如下:


1.源端口號:即發送方的端口號,在TCP連接過程中,對於客戶端,端口號往往由內核分配,無需進程指定;

2.目的端口號:即發送目的的端口號;

3.序號:即爲發送的數據段首個字節的序號;

3.確認序號:在收到對方發來的數據報,發送確認時期待對方下一次發送的數據序號;

4.SYN:用於發送連接請求;

5.ACK:確認序號有效;

6.FIN:斷開連接。


三次握手

三次握手的過程如下:



step1.  由客戶端向服務器端發起連接請求。發送請求標識位SYN置爲1,發送序號爲一個隨機數,這裏假設爲X;

step2.  服務器端接收到連接請求,將標識位ACK置爲1,並將確認序號置爲X+1,然後生成一個隨機數Y作爲發送序號(因爲所確認的數據報的確認序號未初始化);

step3:  客戶端對接收到的確認進行確認,將確認序號置爲Y+1,然後將發送序號置爲X+1(即爲接收到的數據報的確認序號);


這裏有幾點需要說明一下:


1.爲什麼是三次握手而不是兩次。對於step3的作用,假設一種情況,客戶端A想服務器B發送一個連接請求數據報,然後這個數據報在網絡中滯留導致其遲到了,雖然遲到了,但是服務器仍然會接收併發回一個確認數據報。但是A卻因爲久久收不到B的確認而將發送的請求連接失效,等到一段時間後,接到B發送過來的確認,A認爲自己現在沒有發送連接,而B卻一直以爲連接成功了,於是一直在等待A的動作,而A將不會有任何的動作了。這會導致服務器資源白白浪費掉了,因此,兩次握手是不行的,因此需要再加上一次,對B發過來的確認再進行一次確認,即確認這次連接是有效的,從而建立連接。

2.對於雙方,發送序號的初始化爲何值。有的系統中是顯式的初始化序號是0,但是這種已知的初始化值是非常危險的,因爲這會使得一些黑客鑽漏洞,發送一些數據報來破壞連接。因此,初始化序號因爲取隨機數會更好一些,並且是越隨機越安全。


下面是一個簡單的客戶端/服務器端連接程序,在Linux環境下,開啓三個終端,在第一個終端輸入命令




然後在第二個終端運行服務器端程序:




最後在第三個終端運行客戶端程序:




完了之後,我們可以在第一個終端看到抓包的結果,如下:




前三個數據包就是三次握手的三個數據報了。我們逐個分析一下,第一個數據報是由客戶端發送到服務器端,隨機產生一個序號seq = 830831828。然後第二個數據報是由服務器端發回的確認,隨機產生一個序號seq = 2690963443,然後根據接收到的請求數據報將確認序號設置爲830831829。然後第三個數據報是有客戶端對服務器端確認數據報的確認,可以看出確認序號爲2690963444


四次揮手

連接雙方在完成數據傳輸之後就需要斷開連接。由於TCP連接是屬於全雙工的,即連接雙方可以在一條TCP連接上互相傳輸數據,因此在斷開時存在一個半關閉狀態,即有有一方失去發送數據的能力,卻還能接收數據。因此,斷開連接需要分爲四次。主要過程如下:




主要過程如下:


step1.  主機A向主機B發起斷開連接請求,之後主機A進入FIN-WAIT-1狀態;

step2.  主機B收到主機A的請求後,向主機A發回確認,然後進入CLOSE-WAIT狀態

step3.  主機A收到B的確認之後,進入FIN-WAIT-2狀態,此時便是半關閉狀態,即主機A失去發送能力,但是主機B卻還能向A發送數據,並且A可以接收數據。此時主機B佔主導位置了,如果需要繼續關閉則需要主機B來操作了;

step4.  主機B向A發出斷開連接請求,然後進入LAST-ACK狀態;

step5.  主機A接收到請求後發送確認,進入TIME-WAIT狀態,等待2MSL之後進入CLOSED狀態,而主機B則在接受到確認後進入CLOSED狀態;


這裏有幾點需要說明:


1.  爲何主機A在發送了最後的確認後沒有進入CLOSED狀態,反而進入了一個2MSL的TIME-WAIT。主要作用有兩個:第一,確保主機A最後發送的確認能夠到達主機B。如果處於LAST-ACK狀態的主機B一直收不到來自主機A的確認,它會重傳斷開連接請求,然後主機A就可以有足夠的時間去再次發送確認。但是這也只能盡最大力量來確保能夠正常斷開,如果主機A的確認總是在網絡中滯留失效,從而超過了2MSL,最後也無法正常斷開;第二,如果主機A在發送了確認之後立即進入CLOSED狀態。假設之後主機A再次向主機B發送一條連接請求,而這條連接請求比之前的確認報文更早地到達主機B,則會使得主機B以爲這條連接請求是在舊的連接中A發出的報文,並不看成是一條新的連接請求了,即使得這個連接請求失效了,增加2MSL的時間可以使得這個失效的連接請求報文作廢,這樣纔不影響下次新的連接請求中出現失效的連接請求。

2.  在下面的抓包實驗中,爲什麼斷開連接請求報文只有三個,而不是四個。因爲在TCP連接過程中,確認的發送有一個延時(即經受延時的確認),一端在發送確認的時候將等待一段時間,如果自己在這段事件內也有數據要發送,就跟確認一起發送,如果沒有,則確認單獨發送。而我們的抓包實驗中,由服務器端先斷開連接,之後客戶端在確認的延遲時間內,也有請求斷開連接需要發送,於是就與上次確認一起發送,因此就只有三個數據報了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章