TCP協(xié)議是TCP/IP體系中核心一個(gè)協(xié)議,該協(xié)議比起IP協(xié)議,ICMP協(xié)議,UDP協(xié)議都更復(fù)雜,因此這篇文章主要分析TCP協(xié)議在建立連接和斷開(kāi)連接的時(shí)候,狀態(tài)轉(zhuǎn)移以及報(bào)文段的內(nèi)容。
下面,先放一張TCP的狀態(tài)轉(zhuǎn)移圖:
TCP協(xié)議之三次握手
三次握手的過(guò)程是TCP在客戶端和服務(wù)端建立連接的過(guò)程。簡(jiǎn)單的來(lái)說(shuō)三次握手過(guò)程,就是客戶端先發(fā)送一個(gè)連接請(qǐng)求給服務(wù)端,這是第一次握手。服務(wù)端接收到客戶端發(fā)來(lái)的鏈接請(qǐng)求,然后在將確認(rèn)的消息發(fā)給客戶端,這是第二次握手??蛻舳藢?duì)服務(wù)端發(fā)來(lái)的確認(rèn)消息進(jìn)行確認(rèn),然后將確認(rèn)的消息發(fā)給服務(wù)端,這就是三次握手。三次握手之后,鏈接建立。
為什么一定是三次握手才能建立一個(gè)可靠地鏈接?如果不是三次握手,那么在客戶端發(fā)送了鏈接請(qǐng)求之后,服務(wù)端對(duì)這個(gè)請(qǐng)求進(jìn)行確認(rèn),就認(rèn)定這次的鏈接已經(jīng)成功建立,俗稱的二次握手。這樣的方式的弊端在哪里?
考慮這么一種情況,當(dāng)客戶端進(jìn)行第一次握手時(shí),發(fā)送了一個(gè)報(bào)文段,但是這個(gè)報(bào)文段因?yàn)榫W(wǎng)絡(luò)的問(wèn)題,遲遲沒(méi)有到,這時(shí),客戶端又會(huì)再一次發(fā)送一個(gè)連接請(qǐng)求的報(bào)文段給服務(wù)端,這次成功接收,兩者建立連接,并通信結(jié)束,關(guān)閉連接。這之后,因?yàn)榫W(wǎng)絡(luò)延遲的那個(gè)報(bào)文段傳到了服務(wù)端那里,服務(wù)端又以為客戶端要建立新的連接,于是就同意了,向客戶端發(fā)送確認(rèn)。因?yàn)槭嵌挝帐?,所以服?wù)端后續(xù)要做的事情,就是等待客戶端發(fā)送的消息,但是客戶端是不會(huì)理會(huì)服務(wù)端傳來(lái)的確認(rèn),所以服務(wù)端就會(huì)一直在等待客戶端的數(shù)據(jù),白白浪費(fèi)了資源。
抓包分析TCP三次握手的報(bào)文段
現(xiàn)在,詳細(xì)說(shuō)一下三次握手具體是做了什么。
第一次握手,客戶端發(fā)送一個(gè)報(bào)文段給服務(wù)端,該報(bào)文段中標(biāo)志有SYN標(biāo)志,該標(biāo)志表示建立連接,以及一個(gè)初始的序列號(hào)。
第二次握手時(shí),服務(wù)端發(fā)送一個(gè)報(bào)文段給客戶端,該報(bào)文段中標(biāo)志有SYN標(biāo)志,和ACK標(biāo)志。ACK標(biāo)志的值是客戶端發(fā)來(lái)的初始序號(hào)值+ 1,表示對(duì)客戶端進(jìn)行確認(rèn),報(bào)文段中還有服務(wù)端自己的初始序號(hào)。
第三次握手時(shí),客戶端發(fā)送一個(gè)報(bào)文段給服務(wù)端,該報(bào)文段中標(biāo)志只有ACK標(biāo)志,該ACK值是服務(wù)端的初始序列化的值 + 1,表示對(duì)服務(wù)端進(jìn)行確認(rèn),以及還有一個(gè)序號(hào)值,該序號(hào)值為客戶端第一次握手時(shí)的序號(hào)值 + 1。
三次握手建立連接結(jié)束。
圖片上共有三行,每一行代表一次握手。我們先看第一行
可以看出,第一次握手時(shí)55732端口的程序主動(dòng)發(fā)送一個(gè)建立鏈接的報(bào)文段給8888端口。這個(gè)55732端