天天看點

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

【摘要】本文重點分析計算機網絡中TCP協定中的握手和揮手的過程。

【前提說明】

前段時間突然看到了一篇關于TCP/IP模型的文章,心想這段時間在家裡也用wireshark抓了點包,那麼想着想着就覺得需要複習一下網絡知識,于是就有這篇博文的誕生。當然網上關于TCP相關的知識點也是芸芸,閑着無事也可以多google深入了解一下,本文重點在分析TCP協定中的握手和揮手的過程。

【抓包前準備】

既然要抓包,我的裝備是個人電腦,作業系統是Mac OS。抓包工具是wireshark,至于怎麼安裝和一些基本的操作,可以點選參考這篇文章。

用本地電腦模拟server和client,都是localhost的位址,但是我選擇的是不同的端口進行辨別。server的端口号:12345;client的端口号:50784。因為是用的本機做的實驗,是以wireshark監聽的不是網卡而是Loopback:lo0,如圖所示:

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

以下是我模拟client和server的代碼:

1)server端

-Python 代碼
01
#! /usr/bin/python
02
# -*- coding: utf-8 -*-
03
 
04
import socket
05
 
06
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
07
 
08
server_address = ('127.0.0.1', 12345)
09
print "Starting up on %s:%s" % server_address
10
sock.bind(server_address)
11
 
12
sock.listen(1)
13
 
14
while True:
15
    print "Waiting for a connection"
16
    connection, client_address = sock.accept()
17
 
18
    try:
19
        print "Connection from", client_address
20
 
21
        data = connection.recv(1024)
22
        print "Receive '%s'" % data
23
    finally:
24
        connection.close()      

2)client端-Python 代碼

01
# /usr/bin/python
02
# -*- coding: utf-8 -*-
03
 
04
import socket
05
 
06
def check_tcp_status(ip, port):
07
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
08
 
09
    server_address = (ip, port)
10
    print 'Connecting to %s:%s.' % server_address
11
    sock.connect(server_address)
12
 
13
    message = "I'm TCP client"
14
    print 'Sending "%s".' % message
15
    sock.sendall(message)
16
 
17
    print 'Closing socket.'
18
    sock.close()
19
 
20
 
21
if __name__ == "__main__":
22
    print check_tcp_status("127.0.0.1", 12345)      

代碼比較簡單,就是模拟了一次連結,可以多次執行client,client隻要連結成功就會發送一句話“I'm TCP client”,server一直死循環監聽端口,并将接受到的資訊列印到console中。

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

【結果分析】

看到上面的console輸出之後,我們看一下wireshark抓到的結果:

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

我用兩種顔色标了出來,可以看到黃色框中的序号為1、2、3的三次通信過程其實就是我們說的三次握手;握手建立之後的序号為4、5、6便為傳輸資料的過程;而序号7、8、9、10就是我們所說的四次揮手的過程。

我們再進一步細看下握手、揮手這倆過程。

三次握手

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

我們來總結一下握手的規律:

  • 第一次握手:建立連結。用戶端發送連結的請求,發送SYN封包,将Seq設定為0。然後用戶端就進入了SYN_SEND狀态,等待伺服器的确認。
  • 第二次握手:伺服器收到用戶端的SYN封包段。需要對這個SYN封包段進行确認,發送ACK封包,并将Ack設定為1。同時,自己也要發送SYN請求資訊,将Seq設定為0,。伺服器将上述的所有資訊一并發送給用戶端,此時伺服器進入SYN_RECV狀态。
  • 第三次握手:用戶端收到伺服器的ACK和SYN封包後,進行确認,然後将Ack設定為1,Seq設定為1,向伺服器發送ACK封包段,這個封包段發送完畢之後,用戶端和伺服器都進入了ESTABLISHED狀态。就此完成了TCP的三次握手。

四次揮手

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

接着總結下揮手的規律:

  • 第一次揮手:用戶端想伺服器發送一個FIN封包段,将設定Seq為15和Ack為1。此時用戶端進入FIN_WAIT_1狀态。這表示用戶端沒有資料要發送伺服器了,請求關閉連接配接。
  • 第二次揮手:伺服器收到了用戶端發送的FIN封包段,向用戶端回一個ACK封包段,Ack設定為16,Seq設定為1;伺服器進入了CLOSE_WAIT狀态,用戶端收到伺服器傳回的ACK封包之後随即進入FIN_WAIT_2狀态。
  • 第三次揮手:伺服器會觀察自己是否還有資料沒有發送給用戶端,如果有,先把資料發送給用戶端,再發送FIN封包;如果沒有,那麼伺服器直接發送FIN封包給用戶端。請求關閉連接配接,同時伺服器進入LAST_ACK狀态。
  • 第四次揮手:用戶端收到伺服器發送的FIN封包,向伺服器發送ACK封包,将Seq設定為16,Ack設定為2,然後用戶端進入TIME_WAIT狀态;伺服器收到用戶端的ACK封包之後就關閉了連接配接;此時,用戶端等待2msl後依然沒有收到回複,則證明伺服器已正常關閉,用戶端也可以關閉連接配接了。

注意個規律: 每次一方傳回ACK封包的時候,設定Ack=對方傳來的Seq值+1。

【了解TCP/IP模型】

說完TCP協定之後,不能免俗的要聊一下TCP/IP協定模型,該模型是計算機網絡的經典的模型了。該模型由OSI模型演化而來,由原來的7層簡化為了5層,具體如下圖所示:

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手

TCP/IP協定被稱為傳輸控制協定/網際網路協定,又稱網絡通訊協定(Transmission Control Protocol)。是由網絡層的IP協定和傳輸層的TCP協定組成,是一個很大的協定集合。

  • 實體層和資料鍊路層沒有定義任何特定協定,支援所有的标準和專用的協定。
  • 網絡層定義了網絡互聯也就是IP協定,主要包括IP、ARP、RARP、ICMP、IGMP。
  • 傳輸層定義了TCP和UDP(User Datagram Protocol),我們會後面重點介紹一下TCP協定。
  • 應用層定義了HTTP(超文本傳輸協定)、FTP(檔案傳輸協定)、DNS(域名系統)等協定。

TCP/IP的網絡模型分層思想算是非常有借鑒性的系統分層思想。映射到我們的軟體系統上來看,其實我們的軟體系統更多的時候也需要考慮分層,層次之間通過接口來互動。在嚴格的分層系統裡,内部的層隻對相鄰的層次可見,這樣就可以将一個複雜問題分解成增量步驟序列。由于每一層最多隻影響兩層,也給維護帶來了很大的便利。

參考資料:

http://www.cnblogs.com/linyfeng/p/9496126.html

http://zhuanlan.zhihu.com/p/33797520

blog.csdn.net/zhzdeng/article/details/53490386

點選關注,第一時間了解華為雲新鮮技術~

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手