TCP詳解+wireshark抓包演示

簡介

  • TCP理論
  • TCP報文格式
  • 三次握手
    • 三次握手圖解
    • 為什么要三次握手
  • 四次分手
    • 四次分手圖解
    • TCP的半關(guān)閉
  • 實戰(zhàn)抓包演示(Wireshark)

TCP理論

TCP提供了一種面向連接的、可靠的字節(jié)流服務(wù)。
面向連接:接雙方在通信前需要預(yù)先建立一條連接,這猶如實際生活中的打電話。

  • 應(yīng)用數(shù)據(jù)分割成TCP認(rèn)為最適合發(fā)送的數(shù)據(jù)塊。
  • 重傳機制。設(shè)置定時器,等待確認(rèn)包
  • 對首部和數(shù)據(jù)進(jìn)行校驗
  • TCP對收到的數(shù)據(jù)進(jìn)行排序,然后交給應(yīng)用層
  • TCP的接收端丟棄重復(fù)的數(shù)據(jù)
  • TCP還提供流量控制

TCP連接必須要經(jīng)歷三次握手,而釋放一個TCP連接需要四次握手,這是由TCP的半關(guān)閉特性造成的。因為TCP連接時全雙工的,因此,需要TCP兩端要單獨執(zhí)行關(guān)閉。值得注意的是,主動關(guān)閉的一端在發(fā)送FIN之后,依然還能正常接收對方的數(shù)據(jù),只是通知對方它已經(jīng)沒有數(shù)據(jù)需要發(fā)送了,同理,被動關(guān)閉的一端在收到FIN之后,仍然可以發(fā)送數(shù)據(jù),直到它自身同樣發(fā)出FIN之后,才停止發(fā)送數(shù)據(jù)。

TCP報文格式

TCP_format.jpg
  • Source Port和Destination Port:分別占用16位,表示源端口號和目的端口號;用于區(qū)別主機中的不同進(jìn)程,而IP地址是用來區(qū)分不同的主機的,源端口號和目的端口號配合上IP首部中的源IP地址和目的IP地址就能唯一的確定一個TCP連接;
  • Sequence Number:用來標(biāo)識從TCP發(fā)端向TCP收端發(fā)送的數(shù)據(jù)字節(jié)流,它表示在這個報文段中的的第一個數(shù)據(jù)字節(jié)在數(shù)據(jù)流中的序號;主要用來解決網(wǎng)絡(luò)報亂序的問題;
  • Acknowledgment Number:32位確認(rèn)序列號包含發(fā)送確認(rèn)的一端所期望收到的下一個序號,因此,確認(rèn)序號應(yīng)當(dāng)是上次已成功收到數(shù)據(jù)字節(jié)序號加1。不過,只有當(dāng)標(biāo)志位中的ACK標(biāo)志(下面介紹)為1時該確認(rèn)序列號的字段才有效。主要用來解決不丟包的問題;
  • Offset:給出首部中32 bit字的數(shù)目,需要這個值是因為任選字段的長度是可變的。這個字段占4bit(最多能表示15個32bit的的字,即4*15=60個字節(jié)的首部長度),因此TCP最多有60字節(jié)的首部。然而,沒有任選字段,正常的長度是20字節(jié);
  • TCP Flags:TCP首部中有6個標(biāo)志比特,它們中的多個可同時被設(shè)置為1,主要是用于操控TCP的狀態(tài)機的,依次為URGACK,PSH,RSTSYN,FIN。每個標(biāo)志位的意思如下:
    • URG:此標(biāo)志表示TCP包的緊急指針域(后面馬上就要說到)有效,用來保證TCP連接不被中斷,并且督促中間層設(shè)備要盡快處理這些數(shù)據(jù);
    • ACK:此標(biāo)志表示應(yīng)答域有效,就是說前面所說的TCP應(yīng)答號將會包含在TCP數(shù)據(jù)包中;有兩個取值:0和1,為1的時候表示應(yīng)答域有效,反之為0; TCP協(xié)議規(guī)定,只有ACK=1時有效,也規(guī)定連接建立后所有發(fā)送的報文的ACK必須為1
    • PSH:這個標(biāo)志位表示Push操作。所謂Push操作就是指在數(shù)據(jù)包到達(dá)接收端以后,立即傳送給應(yīng)用程序,而不是在緩沖區(qū)中排隊;
    • RST:這個標(biāo)志表示連接復(fù)位請求。用來復(fù)位那些產(chǎn)生錯誤的連接,也被用來拒絕錯誤和非法的數(shù)據(jù)包;
    • SYN:表示同步序號,用來建立連接。SYN標(biāo)志位和ACK標(biāo)志位搭配使用,當(dāng)連接請求的時候,SYN=1,ACK=0;連接被響應(yīng)的時候,SYN=1,ACK=1;這個標(biāo)志的數(shù)據(jù)包經(jīng)常被用來進(jìn)行端口掃描。掃描者發(fā)送一個只有SYN的數(shù)據(jù)包,如果對方主機響應(yīng)了一個數(shù)據(jù)包回來 ,就表明這臺主機存在這個端口;但是由于這種掃描方式只是進(jìn)行TCP三次握手的第一次握手,因此這種掃描的成功表示被掃描的機器不很安全,一臺安全的主機將會強制要求一個連接嚴(yán)格的進(jìn)行TCP的三次握手;
    • FIN: 表示發(fā)送端已經(jīng)達(dá)到數(shù)據(jù)末尾,也就是說雙方的數(shù)據(jù)傳送完成,沒有數(shù)據(jù)可以傳送了,發(fā)送FIN標(biāo)志位的TCP數(shù)據(jù)包后,連接將被斷開。這個標(biāo)志的數(shù)據(jù)包也經(jīng)常被用于進(jìn)行端口掃描。
  • Window:窗口大小

三次握手

三次握手圖解
TCP_hand.jpg
  • 第一次握手:建立連接。客戶端發(fā)送連接請求報文段,將SYN位置為1,Sequence Number為x;然后,客戶端進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器的確認(rèn);
  • 第二次握手:服務(wù)器收到SYN報文段。服務(wù)器收到客戶端的SYN報文段,需要對這個SYN報文段進(jìn)行確認(rèn),設(shè)置Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要發(fā)送SYN請求信息,將SYN位置為1,Sequence Number為y;服務(wù)器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一并發(fā)送給客戶端,此時服務(wù)器進(jìn)入SYN_RECV狀態(tài);
  • 第三次握手:客戶端收到服務(wù)器的SYN+ACK報文段。然后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報文段,這個報文段發(fā)送完畢以后,客戶端和服務(wù)器端都進(jìn)入ESTABLISHED狀態(tài),完成TCP三次握手。

完成了三次握手,客戶端和服務(wù)器端就可以開始傳送數(shù)據(jù)。

為什么要三次握手呢?

防止已失效的連接請求報文突然又傳送到了服務(wù)端。
所謂“已失效的連接請求報文”是這樣產(chǎn)生的。

  • 考慮一種正常的情況
      客戶端發(fā)出連接請求,但因連接請求報文丟失而為收到確認(rèn)。于是客戶端再重傳一次連接請求。后來收到了確認(rèn),建立了連接。數(shù)據(jù)傳送完畢后,就釋放了連接??蛻舳斯舶l(fā)送了兩個連接請求報文,其中一個丟失,第二個到達(dá)了B。沒有“已失效的連接請求報文”
  • 假定出現(xiàn)了一種異常的情況
      即客戶端發(fā)出的第一個連接請求報文段并沒有丟失,而是在某些網(wǎng)絡(luò)節(jié)點長時間滯留了,以致延誤到連接釋放以后的某個時間才到達(dá)了服務(wù)端。本來這事一個早已失效的報文。但服務(wù)端收到失效的請求報文后,就誤以為是A又發(fā)出的一個新的連接請求。于是就向客戶端發(fā)出確認(rèn)報文,同意建立連接。如果不采用三次握手,則服務(wù)端發(fā)出確認(rèn),新的連接就建立了。
      由于客戶度并沒有發(fā)出建立連接的請求,因此不會理睬服務(wù)端的去人,也不會向服務(wù)端發(fā)送數(shù)據(jù)。但服務(wù)端缺以為新的連接已經(jīng)建立,并一直等待客戶端發(fā)來請求。那么服務(wù)端的資源就拜拜浪費了
      采用三次握手的辦法可以防止上述現(xiàn)象的發(fā)生。在剛才的情況下,客戶端不會向服務(wù)端的確認(rèn)發(fā)出確認(rèn)。服務(wù)端收不到確認(rèn),就知道客戶度沒有要求建立連接。

四次分手

TCP連接時全雙工的,因此,需要TCP兩端要單獨執(zhí)行關(guān)閉。簡單來說A、B兩端,A提出斷開連接,則發(fā)包告訴B,讓B不要發(fā)數(shù)據(jù)了。B收到后就對A做一個回應(yīng),然后再發(fā)一個包給A,告訴A不要再發(fā)數(shù)據(jù)了,B就關(guān)閉自己的發(fā)送通道,A收到B的關(guān)閉請求后,也做出回應(yīng)。然后關(guān)閉自己的發(fā)送通道。

四次分手圖解
TCP_bye_img.jpg

當(dāng)客戶端沒有數(shù)據(jù)要發(fā)送是就要釋放客戶端這邊的請求,客戶端會發(fā)送一個報文(沒有數(shù)據(jù)),F(xiàn)lags設(shè)置為FIN=1。服務(wù)端收到報文后先響應(yīng)一個報文,接著再向客戶端請求連接釋放,也是FIN??蛻舳耸盏交貜?fù)后再回復(fù)一個確認(rèn)信息,并進(jìn)入TIME_WAIT狀態(tài),等待2MSL時間。

  • 第一次分手:主機1(可以使客戶端,也可以是服務(wù)器端),設(shè)置Sequence Number和Acknowledgment Number,向主機2發(fā)送一個FIN報文段;此時,主機1進(jìn)入FIN_WAIT_1狀態(tài);這表示主機1沒有數(shù)據(jù)要發(fā)送給主機2了;
  • 第二次分手:主機2收到了主機1發(fā)送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進(jìn)入FIN_WAIT_2狀態(tài);主機2告訴主機1,我“同意”你的關(guān)閉請求;
  • 第三次分手:主機2向主機1發(fā)送FIN報文段,請求關(guān)閉連接,同時主機2進(jìn)入LAST_ACK狀態(tài);
  • 第四次分手:主機1收到主機2發(fā)送的FIN報文段,向主機2發(fā)送ACK報文段,然后主機1進(jìn)入TIME_WAIT狀態(tài);主機2收到主機1的ACK報文段以后,就關(guān)閉連接;此時,主機1等待2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,主機1也可以關(guān)閉連接了。

其他情況:
  服務(wù)端向客戶端發(fā)送 FIN = 1 的釋放連接請求,但這個報文丟失了, A沒有接到不會發(fā)送確認(rèn)信息, 服務(wù)端 超時會重傳,這時客戶端 WAIT_TIME 還能夠接收到這個請求,這時再回復(fù)一個確認(rèn)就行了。(客戶端收到 FIN = 1 的請求后 WAIT_TIME會重新記時)
  另外服務(wù)端存在一個保活狀態(tài),即如果客戶端突然故障死機了,那服務(wù)端那邊的連接資源什么時候能釋放呢? 就是保活時間到了后,服務(wù)端會發(fā)送探測信息, 以決定是否釋放連接。
注意:這里我們假設(shè)是客戶端連接斷開的發(fā)起方,如果是服務(wù)端,流程還是一樣。

TCP的半關(guān)閉

TCP提供了連接的一端在結(jié)束它的發(fā)送后還能接收來自另一端數(shù)據(jù)的能力,這就是TCP的半關(guān)閉。
半關(guān)閉的產(chǎn)生:
客戶端發(fā)送FIN,另一端發(fā)送對這個FIN的ACK報文段。 此時客戶端就處于半關(guān)閉。

實戰(zhàn)抓包演示(Wireshark)

  • 這里使用我們使用的代碼為linux下Socket編程(一)中的代碼。
  • 為了更清楚的看到連接的過程,我們還需要進(jìn)行抓包,這里使用Wireshark。
操作步驟:
  • 打開Wireshark,進(jìn)入抓包狀態(tài)
  • 設(shè)置過濾規(guī)則tcp and tcp.port==9999 and ip.src ==192.166.11.14 or ip.dst==192.166.11.14。我這里演示的服務(wù)端ip是192.166.11.14。
  • 啟動服務(wù)端程序
START_server.png
  • 啟動客戶端然后連接。這里我們直接使用windows的telnet服務(wù)。telnet 192.166.11.14 9999
  • 連接后一次輸入'a' 'b'。發(fā)送兩次數(shù)據(jù)
  • ctrl+c 關(guān)閉服務(wù)端。
抓包結(jié)果
TCP2.png
第一次握手:

這里的截圖我們只接到傳輸層的協(xié)議部分。
向著服務(wù)端發(fā)送一個Syn的報文。其中Sequence Number=0


TCP_hand_1.png

第二次握手:
服務(wù)端向客戶端發(fā)一個Acknowledgment和Syn的報文。Acknowledgment number=1
Sequence number =0


TCP_hand_2.png

第三次握手:
客戶端發(fā)向服務(wù)端一個Acknowledgment的報文。Acknowledgment number=1
Sequence number =1
然后連接建立完成


TCP_hand_3.png

第一次發(fā)送數(shù)據(jù)

TCP_send_1.png

\

第二次發(fā)送數(shù)據(jù)

TCP_send_2.png

第一次分手:

TCP_bye_1.png

第二次分手:

TCP_bye_2.png

第三次分手

TCP_bye_3.png

第四次分手

TCP_bye_4.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容