1. 程式人生 > 其它 >04-TCP/IP三次握手四次揮手

04-TCP/IP三次握手四次揮手

這個東西學了很久,學了忘,忘了學,今天特意學了下,個人感覺簡單易記。

用打電話來形容三次握手,四次揮手。

我給張三打電話。

三次握手

我:喂,張三能聽到嗎?
張三:可以我聽得到,你聽得到嗎?
我:我聽得到

四次揮手

我:張三,我要掛了
張三:收到
張三:我也要掛了
我:收到

你可能會奇怪,掛電話為什麼是四次,難道不能也是三次嗎?就像下面這樣

我:張三,我要掛了
張三:好了,那我也掛了
我:好嘞

答案是,不行,後面會有解釋。

瀏覽器訪問百度的流程

瀏覽器像作業系統請求訪問百度,假設連結是,10.89.21.125: 80,而我這邊瀏覽器對應的ip埠號則是18.147.35.69:33673。一般的,伺服器的埠號都是固定的,而客戶端的埠號則是隨機的。

於是,作業系統操作網絡卡對百度伺服器發起請求,經過三次握手以後,雙方都覺得連線可靠,於是客戶端和瀏覽器的作業系統各自建立了一個傳送佇列和接收佇列,瀏覽器這邊的傳送佇列傳送的資料最終會放入伺服器的接收佇列中,而伺服器那邊的傳送佇列的資料最終會放入瀏覽器這邊的接收佇列。於是瀏覽器只需要往自己這邊的記憶體中放資料和取資料,伺服器那邊同樣如此。

也就是說我們說應用之間的通訊倒不如說是網絡卡之間的通訊,兩邊的應用只是在自己這邊的記憶體中取資料。

建立連線如下圖:

斷開連線如下圖:

完整的互動如下圖:

為何是四次揮手?

請看上面的那幅圖,經過一段時間的互動,客戶端覺得該結束了,於是主動給伺服器傳送請求斷開連線,等於告訴瀏覽器,我這裡已經沒有資料要傳送了。瀏覽器收到以後傳送一個確認已收到。這就是兩次揮手了。

伺服器這邊資料也傳送完畢了,而客戶端也說了,斷開連線,那就斷開唄,於是伺服器也給客戶端傳送一個斷開連線,客戶端感覺資料接收完了,於是給伺服器傳送一個收到。會話就這麼結束了。

實盤驗證

tcpdump -nn -i ens33 port 80這條命令可以抓取網絡卡ens33與伺服器80埠號的互動記錄

curl www.baidu.com:80這條命令可以模擬瀏覽器訪問百度

先在一個視窗執行tcpdump -nn -i ens33 port 80監聽網絡卡活動,在另一個視窗執行命令curl www.baidu.com:80請求百度伺服器。

[root@master ~]# tcpdump -nn -i ens33 port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
# 第一次客戶端請求與伺服器建立連線
18:00:52.886905 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [S], seq 2236384967, win 29200, options [mss 1460,sackOK,TS val 3615 ecr 0,nop,wscale 7], length 0
# 第二次,伺服器表示收到了請求,返回了一個確認,小數點表示ack確認請求
18:00:53.221343 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [S.], seq 2516193507, ack 2236384968, win 8192, options [mss 1400,sackOK,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,wscale 5], length 0
# 第三次握手,客戶端給瀏覽器傳送一個確認收到伺服器已經做好連線準備的訊息。
18:00:53.221386 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 1, win 229, length 0

# 這裡是客戶端真正的請求,表示我需要什麼資源,這裡的 length!=0
18:00:53.221575 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [P.], seq 1:78, ack 1, win 229, length 77: HTTP: GET / HTTP/1.1
# 伺服器返回我知道了,只是單純的確認返回,length都是0
18:00:53.556998 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [.], ack 78, win 776, length 0
# 瀏覽器返回資料
18:00:53.570395 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [P.], seq 1:2782, ack 78, win 776, length 2781: HTTP: HTTP/1.1 200 OK
# 客戶端返回確認資料接收到了
18:00:53.570425 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 2782, win 272, length 0

# 這中間許多的互相確認是因為網路問題,不算真正的斷開連線
18:00:53.570797 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [F.], seq 78, ack 2782, win 272, length 0
18:00:53.771156 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [.], seq 1:1301, ack 78, win 776, length 1300: HTTP: HTTP/1.1 200 OK
18:00:53.771226 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 2782, win 272, options [nop,nop,sack 1 {1:1301}], length 0
18:00:54.173484 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [.], seq 1:1301, ack 78, win 776, length 1300: HTTP: HTTP/1.1 200 OK
18:00:54.173530 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 2782, win 272, options [nop,nop,sack 1 {1:1301}], length 0

# 客戶端連續三次傳送請求斷開連線,伺服器才收到
18:00:54.273901 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [F.], seq 78, ack 2782, win 272, length 0
18:00:55.280058 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [F.], seq 78, ack 2782, win 272, length 0
18:00:57.296353 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [F.], seq 78, ack 2782, win 272, length 0

# 伺服器表示收到客戶端想斷開連線
18:00:57.629521 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [.], ack 79, win 776, length 0
# 伺服器也想斷開連線
18:00:57.629565 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [F.], seq 2782, ack 79, win 776, length 0
18:00:57.629583 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 2783, win 272, length 0
# 這中間可能是網路問題,兩邊互相確認了好幾遍
18:00:58.434519 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [F.], seq 2782, ack 79, win 776, length 0
18:00:58.434552 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 2783, win 272, length 0
18:01:00.045603 IP 103.235.46.39.80 > 192.168.1.120.40344: Flags [F.], seq 2782, ack 79, win 776, length 0
18:01:00.045640 IP 192.168.1.120.40344 > 103.235.46.39.80: Flags [.], ack 2783, win 272, length 0