天天看點

Linux - Tcp連接配接建立和釋放的三次握手四次揮手

一、TCP封包段首部格式    

Linux - Tcp連接配接建立和釋放的三次握手四次揮手

    源端口/目的端口:各占2個位元組,分别寫入源端口和目的端口,端口是傳輸層與應用層的服務接口

    序号:占4個位元組,TCP連接配接中傳送的資料流中每一個位元組都有一個序号,序号字段指本封包段所發送的資料的第一個位元組的序号

    确認号:占4個位元組,是期望收到對方下一個封包的第一個資料位元組的序号

    資料偏移:占4個位元組,它指出TCP封包的資料距離TCP封包段的起始處有多遠

    保留:占6個位元組,保留今後使用,但目前應都位0

    标志URG:緊急置位,當URG=1時告訴系統此封包段中有緊急資料

    标志ACK:響應确認,TCP規定在連接配接建立後所有封包的傳輸都必須把ACK置為1;

    标志PSH:資料推送,當一端的應用程序希望在鍵入一個指令後立即就能收到對方的響應時将PSH置為1

    标志RST:連接配接重置,當RST=1時表明TCP連接配接中出現嚴重差錯,必須釋放連接配接然後再重建立立連接配接

    标志SYN:建立連接配接,用來同步序号,當SYN=1和ACK=0時表明是連接配接請求封包,若同意連接配接則響應封包中應該使SYN=1和ACK=1

    标志FIN:關閉連接配接,當FIN=1時表明此封包的發送方的資料已經發送完畢并且要求釋放

    視窗:占2個位元組,指的是通知接收方,發送本封包你需要有多大的空間來接受

    檢驗和:占2個位元組,校驗首部和資料這兩部分

    緊急指針:占2個位元組,指出本封包段中的緊急資料的位元組數

    選項:長度可變,定義一些其他的可選的參數

    填充: 這是為了使整個首部長度是4位元組的整數倍的字段

二、TCP連接配接建立(三次握手)  

Linux - Tcp連接配接建立和釋放的三次握手四次揮手

    伺服器程序先建立傳輸控制塊TCB,時刻準備接受客戶程序的連接配接請求,此時伺服器就進入了LISTEN(監聽)狀态;

    客戶程序也是先建立傳輸控制塊TCB,然後向伺服器發出連接配接請求封包,這是封包首部中的同部位SYN=1,同時選擇一個初始序列号 seq=x ,此時,TCP用戶端程序進入了 SYN-SENT(同步已發送狀态)狀态。TCP規定,SYN封包段(SYN=1的封包段)不能攜帶資料,但需要消耗掉一個序号。

    伺服器收到請求封包後,如果同意連接配接,則發出确認封包。确認封包中應該 ACK=1,SYN=1,确認号是ack=x+1,同時也要為自己初始化一個序列号 seq=y,此時,TCP伺服器程序進入了SYN-RCVD(同步收到)狀态。這個封包也不能攜帶資料,但是同樣要消耗一個序号。

    客戶程序收到确認後,還要向伺服器給出确認。确認封包的ACK=1,ack=y+1,自己的序列号seq=x+1,此時,TCP連接配接建立,用戶端進入ESTABLISHED(已建立連接配接)狀态。TCP規定,ACK封包段可以攜帶資料,但是如果不攜帶資料則不消耗序号。

    伺服器收到用戶端的ACK确認資訊并校驗後也進入ESTABLISHED狀态,此時再傳回資訊,而此後雙方就進入了資料通信階段。  

#用戶端發送一個SYN封包連接配接伺服器的端口,用戶端初始序号為4637811,同時報告視窗大小和MSS值
  17:43:47.475512 IP 192.168.3.43.51843 > 192.168.2.222.8080: S 4637811:4637811(0) win 64240 <mss 1460,nop,wscale 8,nop,nop,sackOK>
  #伺服器傳回包含伺服器初始序号即653770253的SYN封包作為應答,同時将确認序号設定為用戶端序号+1即4637812以對用戶端SYN封包進行确認
  17:43:47.475562 IP 192.168.2.222.8080 > 192.168.3.43.51843: S 653770253:653770253(0) ack 4637812 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
  #用戶端發送将伺服器初始序号+1即653770254的ACK封包作為應答。這裡的标志位"."表示SFRP四個辨別位都是0,當然此時的ACK辨別位是1        
  17:43:47.475935 IP 192.168.3.43.51843 > 192.168.2.222.8080: . ack 653770254 win 2053
           

三、TCP連接配接的釋放(四次揮手)

    用戶端程序發出連接配接釋放封包,并且停止發送資料。釋放資料封包首部,FIN=1,其序列号為seq=u(等于前面已經傳送過來的資料的最後一個位元組的序号加1),此時,用戶端進入FIN-WAIT-1(終止等待1)狀态。 TCP規定,FIN封包段即使不攜帶資料,也要消耗一個序号。

    伺服器收到連接配接釋放封包,發出确認封包,ACK=1,ack=u+1,并且帶上自己的序列号seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀态。TCP伺服器通知高層的應用程序,用戶端向伺服器的方向就釋放了,這時候處于半關閉狀态,即用戶端已經沒有資料要發送了,但是伺服器若發送資料,用戶端依然要接受。這個狀态還要持續一段時間,也就是整個CLOSE-WAIT狀态持續的時間。

    用戶端收到伺服器的确認請求後,此時,用戶端就進入FIN-WAIT-2(終止等待2)狀态,等待伺服器發送連接配接釋放封包(在這之前還需要接受伺服器發送的最後的資料)。

    伺服器将最後的資料發送完畢後,就向用戶端發送連接配接釋放封包,FIN=1,ack=u+1,由于在半關閉狀态,伺服器很可能又發送了一些資料,假定此時的序列号為seq=w,此時,伺服器就進入了LAST-ACK(最後确認)狀态,等待用戶端的确認。

    用戶端收到伺服器的連接配接釋放封包後,必須發出确認,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此時,用戶端就進入了TIME-WAIT(時間等待)狀态。注意此時TCP連接配接還沒有釋放,必須經過2∗∗MSL(最長封包段壽命)的時間後,當用戶端撤銷相應的TCB後,才進入CLOSED狀态。

    伺服器隻要收到了用戶端發出的确認,立即進入CLOSED狀态。同樣,撤銷TCB後,就結束了這次的TCP連接配接。可以看到,伺服器結束TCP連接配接的時間要比用戶端早一些。

#用戶端發起關閉請求,發送一個FIN封包,用戶端封包序号為653770398
    17:43:51.064361 IP 192.168.2.222.8080 > 192.168.3.43.51843: F 653770398:653770398(0) ack 4637815 win 46
    #服務端接受到資訊後,首先傳回ACK封包,表明自己已經收到消息,确認序号為用戶端封包需要+1即653770399
    17:43:51.065064 IP 192.168.3.43.51843 > 192.168.2.222.8080: . ack 653770399 win 2052
    #服務端在準備好關閉之前,最後發送給用戶端一個FIN封包,詢問用戶端是否已經準備好關閉,伺服器端封包序号4637815
    17:43:51.066797 IP 192.168.3.43.51843 > 192.168.2.222.8080: F 4637815:4637815(0) ack 653770399 win 2052
    #用戶端接受到服務端發送的消息後,傳回一個ACK封包,封包序号為伺服器封包序号+1即4637816
    17:43:51.066816 IP 192.168.2.222.8080 > 192.168.3.43.51843: . ack 4637816 win 46 
           

四、Tcp連接配接中的端口狀态轉換

    1、用戶端端口狀态轉換

Linux - Tcp連接配接建立和釋放的三次握手四次揮手

    2、服務端端口狀态轉換    

Linux - Tcp連接配接建立和釋放的三次握手四次揮手
Linux - Tcp連接配接建立和釋放的三次握手四次揮手

繼續閱讀