關於TCP的三次握手建立連接和四次揮手斷開連接

一、整理文章起因

工作中一次和其他業務對接接口,在使用過程中出現了我這邊請求對方接口,而對方說沒有收到我的請求,並且該現象還在持續發生,於是我通過tcpdump進行抓包分析,抓包結果如下:

 

 

 這次的抓包和標準的四次揮手斷開連接有點區別,想着很多時候現在面試一般都會問這些基礎的協議相關內容,三次握手四次斷開連接,TCP,UDP等,所以也想通過這次複習,把很多遺漏地方補充一下

 

二、TCP報文格式

 

對上圖重要字段說明:

Source Port: 源端口,16位

Destination Port:目的端口16位

Sequence Number:序列號,32位

Acknowledgment Number:確認序號,32位

 

Control Bits:

URG:  緊急指針有效

ACK:  確認序號有效

PSH:  Push Function

RST:  復位TCP連接

SYN:  發起一個新連接

FIN:  沒有更多的數據發送 ,釋放一個tcp連接

 

注意:不要把確認序號和標誌位中的ACK弄混了,Ack確認號是對發起方的Seq+1 

 

關於TCP連接過程中不同連接狀態的說明:

  1. LISTEN:偵聽來自遠方的TCP端口的連接請求. 
  2. SYN-SENT:在發送連接請求後等待匹配的連接請求
  3. SYN-RECEIVED:在收到和發送一個連接請求後等待對方對連接請求的確認
  4. ESTABLISHED:代表一個打開的連接,可以接收數據
  5. FIN-WAIT-1:等待遠程TCP連接中斷請求,或先前的連接中斷請求的確認
  6. FIN-WAIT-2:從遠程TCP等待連接中斷請求
  7. CLOSE-WAIT:等待從本地用戶發來的連接中斷請求
  8. CLOSING:等待遠程TCP對連接中斷的確認
  9. LAST-ACK:等待原來的發向遠程TCP的連接中斷請求的確認
  10. TIME-WAIT:等待足夠的時間以確保遠程TCP接收到連接中斷請求的確認 
  11. CLOSED:沒有任何連接狀態

 

 

爲了方便理解,寫一個一個socket服務端和客戶端,抓包分析內容,來看一個標準的tcp三次握手和四次揮手

服務端代碼:

import socket,os



server = socket.socket()
server.bind(('0.0.0.0',6666))
server.listen()


while True:
     conn,addr = server.accept()
     print("一個新的連接:",addr)
     try:
          while True:
               print("等待接收")
               data = conn.recv(1024)
               if not data:
                  break
               print("recv data:",data)
               res = data.decode("utf-8").upper()
               conn.send(res.encode())
               print("send done")
     except Exception as e:
           print(e)
          
server.close()

客戶端代碼:

import socket,os

client = socket.socket()

client.connect(('192.168.188.106', 6666))

while True:
    cmd = input(">>:").strip()
    client.send(cmd.encode("utf-8"))
    cmd_res = client.recv(1024)
    print(cmd_res.decode())
client.close()

抓包對客戶端和服務端的的通信過程進行分析,這是一個非常的標準的三次握手和四次揮手過程:

 

 先看針對上圖中的三次握手:

 在看看四次揮手的整理

 

 

 

 

 

 

 

 關於TCP斷開連接的說明

從上面的圖我們可以看到是客戶端主動斷開連接,那麼我們站在客戶端的服務端兩方面

對於客戶端來說:

  1. 發送FIN告訴服務端要關閉連接,並自己進入FIN-WAIT-1狀態,這個時候就不再處理和發送應用層用戶的數據
  2. 收到服務端對FIN的ACK後,客戶端進入FIN-WAIT-2狀態,這個時候依然可以接收服務端的數據,如果收不到對方的ACK會再次發送之前包含FIN在內的消息
  3. 收到服務端發送的FIN之後說明服務端也沒有數據發送並關閉連接了,此時客戶端發送ACK對服務端的FIN進行確認並進入TIME-WAIT,然後等待2MS連接關

對於服務端來說:

  1. 收到客戶端發送的FIN,發送ACK對這個FIN消息進行確認,並進入到CLOSE-WAIT狀態
  2. 服務單在發送FIN的之前,如果還有未發送的數據,可以繼續發送,發送FIN之後進入LAST-ACK
  3. 等待客戶端的ACK消息確認自己的FIN完成關閉,如果客戶端沒有確認會再次發送FIN

 

 

小結:

發送FIN之後的一端將不會再發送數據

被斷開的一方收到FIN後,給對方發送ACK表示收到,並自己的狀態更改爲CLOS-WAIT,此時TCP連接處於半關閉狀態。被斷開的一方仍然可以發送數據

 

 

 

 

 

 

 

 

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