簡介
相信很多人都聽說過tcp/ip協(xié)議中的三次握手建立連接和四次握手?jǐn)嚅_連接膳音。在面試的時候召衔,總會被面試官問及。然后很多人并不知道具體的過程祭陷。下面我將通過wireshark抓包工具來分析socket建立連接時的三次握手和斷開連接的四次握手苍凛。
TCP/IP握手趣席,數(shù)據(jù)傳輸,揮手
這里先惡補(bǔ)一下TCP/IP相關(guān)的知識毫深,如果了解吩坝,可以直接滾動到下一節(jié)內(nèi)容跳毒姨。
-
TCP中的FLAGS字段
SYN(synchronous):建立連接
ACK(acknowledgement): 響應(yīng)
PSH(push):DATA數(shù)據(jù)傳輸
FIN(finish):關(guān)閉連接
RST(reset重置)
URG(urgent) 連接重置ACK是可能與SYN哑蔫,F(xiàn)IN等同時使用的,比如SYN和ACK可能同時為1弧呐,它表示的就是建立連接之后的響應(yīng)闸迷,如果只是單個的一個SYN,它表示的只是建立連接俘枫。
TCP的幾次握手就是通過這樣的ACK表現(xiàn)出來的腥沽。但SYN與FIN是不會同時為1的,因為前者表示的是建立連接鸠蚪,而后者表示的是斷開連接今阳。
RST一般是在FIN之后才會出現(xiàn)為1的情況,表示的是連接重置茅信。一般地盾舌,當(dāng)出現(xiàn)FIN包或RST包時,我們便認(rèn)為客戶端與服務(wù)器端斷開了連接蘸鲸;而當(dāng)出現(xiàn)SYN和SYN+ACK包時妖谴,我們認(rèn)為客戶端與服務(wù)器建立了一個連接。
PSH為1的情況酌摇,一般只出現(xiàn)在 DATA內(nèi)容不為0的包中膝舅,也就是說PSH為1表示的是有真正的TCP數(shù)據(jù)包內(nèi)容被傳遞。
其它字段
Seq(Sequence number):順序號碼
Ack(Acknowledge number):確認(rèn)號碼-
三次握手(建立連接)
第一次握手:主機(jī)A發(fā)送位碼為syn=1,隨機(jī)產(chǎn)生seqnumber=1234567的數(shù)據(jù)包 到服務(wù)器窑多,主機(jī)B由SYN=1知道仍稀,A要求建立聯(lián)機(jī);第二次握手:主機(jī)B收到請求后要確認(rèn)聯(lián)機(jī)信息埂息,向A發(fā)送ack number=(主機(jī)A的seq+1),syn=1,ack=1,隨機(jī)產(chǎn)生seq=7654321的包
第三次握手:主機(jī)A收到后檢查ack number是否正確技潘,即第一次發(fā)送的seq number+1,以及位碼ack是否為1,若正確耿芹,主機(jī)A會再發(fā)送ack number=(主機(jī)B的seq+1),ack=1崭篡,主機(jī)B收到后確認(rèn)seq值與ack=1則連接建立成功。
-
四次握手(斷開連接)
由于TCP連接是全雙工的吧秕,因此每個方向都必須單獨(dú)進(jìn)行關(guān)閉琉闪。這原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個FIN來終止這個方向的連接。收到一個 FIN只意味著這一方向上沒有數(shù)據(jù)流動砸彬,一個TCP連接在收到一個FIN后仍能發(fā)送數(shù)據(jù)颠毙。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動關(guān)閉斯入,而另一方執(zhí)行被動關(guān)閉。第一次揮手:主動關(guān)閉方發(fā)送一個FIN=1蛀蜜,主動關(guān)閉方可以繼續(xù)接受數(shù)據(jù)刻两。
第二次揮手:被動關(guān)閉方發(fā)送一個ACK=1給對方。
第三次揮手:被動關(guān)閉方發(fā)送一個FIN=1滴某。
第四次揮手:主動關(guān)閉方發(fā)送一個ACK=1給被動關(guān)閉方磅摹。
Wireshark抓包
這里我用socket做了一個長鏈接,當(dāng)客戶端連接成功后霎奢,服務(wù)端寫數(shù)據(jù)到客戶端户誓。
192.168.2.2:服務(wù)端
192.168.2.4:客戶端
服務(wù)端寫數(shù)據(jù)代碼
val p = ByteArray(l + 3)
p[0] = 1
p[1] = (l and 0x0000FF00 shr 8).toByte()
p[2] = (l and 0x000000FF).toByte()
d.copyInto(p,3,0,l)
outputStream.write(p)
outputStream.flush()
這里一共寫了61個字節(jié)的數(shù)據(jù),第二個和第三個放的是后面數(shù)據(jù)的長度(58個字節(jié))幕侠。
抓包帝美,過濾:ip.addr eq 192.168.2.2 and ip.addr eq 192.168.2.4
- 三次握手
No.分別是:2,3晤硕,4 -
數(shù)據(jù)傳輸
No.分別是:5悼潭,6
因為在三次握手成功后,服務(wù)端會寫數(shù)據(jù)給客戶端舞箍,所以這里有數(shù)據(jù)的傳輸舰褪,由于TCP是可靠傳輸,需要對接收到的TCP報文進(jìn)行確認(rèn)创译,所以有了No.為6的確認(rèn)過程抵知。
傳輸?shù)臄?shù)據(jù)可以從Wireshark窗口的Data處查看
Wireshark_data.png - 四次揮手
No.分別是:254,274软族,282刷喜,302,303立砸,其中有一個是發(fā)生了重傳掖疮。
我是通過結(jié)束服務(wù)端進(jìn)程(Android應(yīng)用),來斷開socket連接。其中254颗祝,274總274發(fā)生了重傳浊闪,可以認(rèn)為第一次揮手。
至于每個過程SYN螺戳,ACK搁宾,F(xiàn)IN,PSH的變化可以從Info欄可以清晰的看到倔幼。選擇某一過程盖腿,點(diǎn)開下面對應(yīng)的三角符號,可以查看更加詳細(xì)的信息。