專業(yè)知識
HTTP 的三次握手是一個非常重要的面試和考試考點,但是今天早上看書上的一幅圖和三段話將近看了半個小時祸挪,于是來總結(jié)一下佑刷。
連接狀態(tài)
- CLOSED:表示初始狀態(tài)。
- LISTEN: 服務(wù)器端的某個SOCKET處于監(jiān)聽狀態(tài)棒动,可以接受連接了。
- SYN_SENT:表示客戶端已發(fā)送 SYN 報文肝劲。
- SYN_RCVD:表示服務(wù)器接受到了 SYN 報文迁客。
- ESTABLISHED:表示連接已經(jīng)建立。
HTTP 的三次握手使用的是 TCP 協(xié)議辞槐,所以先看一下 TCP 的報文段首部掷漱,三次握手需要注意到的是用紅線括起來的部分。
字段介紹
- ACK 確認(rèn)字段:在連接建立后所有傳送的報文段 ACK 必須為 1 榄檬。
- SYN 同步字段:連接建立時使用同步序號卜范。
- FIN 終止字段:FIN = 1 是表示釋放一個連接。
- 序號 seq :發(fā)送了多少被成功接受數(shù)據(jù)鹿榜。
- 確認(rèn)號 ack:接受了多少數(shù)據(jù)海雪。
注意點
ACK = 1 不攜帶數(shù)據(jù)不消耗序號。
SYN = 1 不能攜帶數(shù)據(jù)并且要消耗一個序號舱殿。
抓包示例
示例分析
192.168.1.11 為客戶端 A奥裸,42.121.252.58 為服務(wù)器 B。
- 客戶端請求連接發(fā)送 SYN 產(chǎn)生一個為 x = 0 的序號 seq 沪袭。
- 服務(wù)器接受連接湾宙,ACK = x + 1 = 1 并產(chǎn)生 y = 0 的序號 seq;發(fā)送 SYN ACK seq = 0 ack = 1 到客戶端冈绊。
- 客戶端發(fā)現(xiàn)服務(wù)器接受了連接請求返回了 ack侠鳄,seq = x;同時接受服務(wù)器的請求 ack = y + 1 = 1死宣。
- 因為上個傳輸伟恶,只傳輸了一個 ACK 沒有數(shù)據(jù),所以看第四條線 seq = 1毅该,ack = 1博秫。
收獲:看 2 這個列表項,發(fā)送端的 seq 字段需要接收到服務(wù)器段的 ack 才會變化鹃骂,這個時候 服務(wù)器 ack = 客戶端 seq 台盯。
所以我才會有下面對 seq 和 ack 的理解。
- 序號 seq :發(fā)送了多少被成功接受數(shù)據(jù)畏线。
- 確認(rèn)號 ack:接受了多少數(shù)據(jù)静盅。
面試問題
為什么使用三次握手?
為了防止已失效的連接請求報文段突然又傳送到了服務(wù)端寝殴,因而產(chǎn)生錯誤 ——謝希仁著《計算機網(wǎng)絡(luò)》第四版
謝希仁版《計算機網(wǎng)絡(luò)》中的例子是這樣的蒿叠,“已失效的連接請求報文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個連接請求報文段并沒有丟失,而是在某個網(wǎng)絡(luò)結(jié)點長時間的滯留了蚣常,以致延誤到連接釋放以后的某個時間才到達(dá)server市咽。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后抵蚊,就誤認(rèn)為是client再次發(fā)出的一個新的連接請求施绎。于是就向client發(fā)出確認(rèn)報文段溯革,同意建立連接。假設(shè)不采用“三次握手”谷醉,那么只要server發(fā)出確認(rèn)致稀,新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求俱尼,因此不會理睬server的確認(rèn)抖单,也不會向server發(fā)送數(shù)據(jù)。但server卻以為新的運輸連接已經(jīng)建立遇八,并一直等待client發(fā)來數(shù)據(jù)矛绘。這樣,server的很多資源就白白浪費掉了刃永。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生货矮。例如剛才那種情況,client不會向server的確認(rèn)發(fā)出確認(rèn)斯够。server由于收不到確認(rèn)次屠,就知道client并沒有要求建立連接■ù蹋”主要目的防止server端一直等待劫灶,浪費資源。
觀察 SYN 的含義:同部字段掖桦。如果客戶端和服務(wù)器端都需要使用 SYN-ACK 機制同步一下的話本昏,最少是需要 3 次握手的。另一方面服務(wù)器資源相對于客戶端資源是更加重要一點枪汪。
參考文章