三次握手
提到 tcp 協(xié)議,每個人大概都能想到建立 tcp 連接需要三次握手。初次接觸,很自然地會提出一個疑問:為什么需要三次握手?兩次不行嗎?
要回答這個問題之前,我們先回顧一下什么 tcp。tcp 協(xié)議是傳輸層協(xié)議,為上層協(xié)議如 http、ftp 等提供雙向的、可靠的、按序的字節(jié)流邏輯信道。tcp 建立連接的三次握手過程如下:
client server
SYN
------------------------------------->
SYN+ACK
<-------------------------------------
ACK
------------------------------------->
先明確一下三次握手,每次握手都在做什么:
1、c 端向 s 端發(fā)送 syn
“我要和你通信咯。我發(fā)送的 packet 的初始序號從 x 開始。一定要從 x 序號開始收我發(fā)的 packet 啊,這樣才能保證信息重組后不亂序呀。你如果收到了,就告訴你收到了信息。并且把你要發(fā)送的 packet 的初始序號 y 發(fā)給我,我好確認你給我發(fā)的 packet”
2、s 端向 c 端發(fā)送 ack+syn
"我收到你的信息了。我會從序號 x 開始確認你發(fā)的 packet。這是我將要發(fā)你的 packet 的初始序號。等你確認收到我的消息時,我們就可通信啦"
3、c 端向 s 端發(fā)送 ack
"我收到了你的初始序號了。現(xiàn)在我們可以可靠地進行通信了"
用 linux 下的 dump 命令查看一下握手過程
監(jiān)聽網(wǎng)卡
? ~ sudo tcpdump host www.zhihu.com
curl 請求
? ~ curl -I www.zhihu.com
HTTP/1.1 301 Moved Permanently
Date: Sat, 28 Oct 2017 01:43:25 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Set-Cookie: aliyungf_tc=AQAAAM2jCXsmxwAAk6P53EBJXABbb44Z; Path=/; HttpOnly
Location: https://www.zhihu.com/
X-Req-ID: 13F2DBE59F3E0BD
Server: ZWS
Vary: Accept-Encoding
dump 輸出
09:43:24.475574 IP waydembp.63532 > 118.178.213.186.http: Flags [SEW], seq 609956406, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 222104353 ecr 0,sackOK,eol], length 0
09:43:24.559886 IP 118.178.213.186.http > waydembp.63532: Flags [S.E], seq 1238093818, ack 609956407, win 14600, options [mss 1444,nop,nop,sackOK,nop,wscale 7], length 0
09:43:24.559954 IP waydembp.63532 > 118.178.213.186.http: Flags [.], ack 1, win 8192, length 0
09:43:24.560131 IP waydembp.63532 > 118.178.213.186.http: Flags [P.], seq 1:79, ack 1, win 8192, length 78: HTTP: HEAD / HTTP/1.1
09:43:24.605720 IP 118.178.213.186.http > waydembp.63532: Flags [.], ack 79, win 115, length 0
09:43:24.684824 IP 118.178.213.186.http > waydembp.63532: Flags [P.], seq 1:315, ack 79, win 115, length 314: HTTP: HTTP/1.1 301 Moved Permanently
09:43:24.684909 IP waydembp.63532 > 118.178.213.186.http: Flags [.], ack 315, win 8182, length 0
09:43:24.685170 IP waydembp.63532 > 118.178.213.186.http: Flags [F.], seq 79, ack 315, win 8192, length 0
09:43:24.729360 IP 118.178.213.186.http > waydembp.63532: Flags [F.], seq 315, ack 80, win 115, length 0
09:43:24.729415 IP waydembp.63532 > 118.178.213.186.http: Flags [.], ack 316, win 8192, length 0
前三條記錄體現(xiàn)了握手過程。
關于初始 init seq num 可以看 [rfc-761 page27]
但是從輸出看,我有一個疑惑:s 端的 init seq 為 1238093818(line 2),但是 c 端請求數(shù)據(jù)卻是從 seq 1 (line 4)開始?
從這篇博文來看,第三行之后的 seq num 應該都是 relative seq num。就是第三行之后的 seq num 都是相對于 init seq 的偏移量。所以就可以理解為什么第四行編號從 1 開始。