TCP的三次握手與四次揮手
TCP(Transmission Control Protocol,傳輸控制協(xié)議)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。TCP的主要目標(biāo)是提供一種可靠的、有序的和錯(cuò)誤校驗(yàn)的數(shù)據(jù)傳輸方式,以確保數(shù)據(jù)在網(wǎng)絡(luò)中的可靠傳輸。
主要特點(diǎn):
- 面向連接:在傳輸數(shù)據(jù)之前,必須先建立TCP連接。連接是可靠的服務(wù),具有固定的連接端點(diǎn)。
- 可靠傳輸:TCP提供了數(shù)據(jù)傳輸?shù)拇_認(rèn)和重傳機(jī)制,以確保數(shù)據(jù)的順序和完整性。如果數(shù)據(jù)在傳輸過程中丟失或損壞,TCP會(huì)重新發(fā)送數(shù)據(jù),以確保接收端能夠正確地接收到數(shù)據(jù)。
- 流量控制:TCP提供了一種機(jī)制,用于控制發(fā)送方發(fā)送數(shù)據(jù)的速度,以防止接收方來不及接收數(shù)據(jù)而造成數(shù)據(jù)丟失。
- 擁塞控制:當(dāng)網(wǎng)絡(luò)擁塞時(shí),TCP會(huì)降低發(fā)送數(shù)據(jù)的速度,以減少網(wǎng)絡(luò)擁塞。TCP使用一系列算法來檢測和防止網(wǎng)絡(luò)擁塞。
- 字節(jié)流:TCP將應(yīng)用程序中的數(shù)據(jù)作為字節(jié)流發(fā)送,沒有消息邊界的概念。這意味著發(fā)送端可以連續(xù)發(fā)送數(shù)據(jù),而接收端必須按順序接收字節(jié)流并重新組合成有意義的數(shù)據(jù)。
TCP廣泛應(yīng)用于互聯(lián)網(wǎng)協(xié)議(IP)網(wǎng)絡(luò)中,是互聯(lián)網(wǎng)協(xié)議(IP)的重要組成部分。許多應(yīng)用程序和協(xié)議都使用TCP作為其傳輸層協(xié)議,例如HTTP、FTP、SMTP和許多其他協(xié)議。
在發(fā)送數(shù)據(jù)前,通信雙方必須在彼此間建立一條連接。所謂的“連接”,其實(shí)是客戶端和服務(wù)端保存的一份關(guān)于對方的信息,如ip地址、端口號等。TCP可以看成是一種字節(jié)流,它會(huì)處理IP層或以下的層的丟包、重復(fù)以及錯(cuò)誤問題。在連接的建立過程中,雙方需要交換一些連接的參數(shù)。這些參數(shù)可以放在TCP頭部。一個(gè)TCP連接由一個(gè)4元組構(gòu)成,分別是兩個(gè)IP地址和兩個(gè)端口號。一個(gè)TCP連接通常分為三個(gè)階段:連接、數(shù)據(jù)傳輸、退出(關(guān)閉)。通過三次握手建立一個(gè)鏈接,通過四次揮手來關(guān)閉一個(gè)連接。當(dāng)一個(gè)連接被建立或被終止時(shí),交換的報(bào)文段只包含TCP頭部,而沒有數(shù)據(jù)。
TCP報(bào)文頭部結(jié)構(gòu)
圖片
- 源端口和目的端口:用于標(biāo)識發(fā)送和接收數(shù)據(jù)的進(jìn)程。
- 序號:seq序號,占32位,用來標(biāo)識從TCP源端向目的端發(fā)送的字節(jié)流,發(fā)起方發(fā)送數(shù)據(jù)時(shí)對此進(jìn)行標(biāo)記,以便在接收端重新排序并組裝數(shù)據(jù)。
- 確認(rèn)號:ack序號,占32位,只有ACK標(biāo)志位為1時(shí),確認(rèn)序號字段才有效,ack=seq+1,用于確認(rèn)接收到的數(shù)據(jù),并告訴發(fā)送端下一個(gè)期望接收的字節(jié)號。
- 頭部長度:指示TCP頭部的大?。ㄒ?2位字為單位)。
- 標(biāo)志位:URG、ACK、PSH、RST、SYN和FIN等標(biāo)志,用于指示TCP的狀態(tài)和操作。標(biāo)志位具體含義如下:
- ACK:確認(rèn)序號有效。
- FIN:釋放一個(gè)連接。
- PSH:接收方應(yīng)該盡快將這個(gè)報(bào)文交給應(yīng)用層。
- RST:重置連接。SYN:發(fā)起一個(gè)新連接。
- URG:緊急指針(urgent pointer)有效。
- 窗口大?。河糜诹髁靠刂疲甘窘邮斩丝山邮盏淖畲髷?shù)據(jù)量。
- 校驗(yàn)和:用于檢測數(shù)據(jù)在傳輸過程中的錯(cuò)誤。
- 緊急指針:用于標(biāo)識緊急數(shù)據(jù)的字節(jié)號。
- TCP選項(xiàng):可變長的可選信息,例如最大段大小、時(shí)間戳等。
三次握手
TCP的三次握手過程是建立TCP連接的過程,目的是為了初始化通信雙方sequence number的初始值。
圖片
- 第一次握手:客戶端發(fā)送SYN包(SYN=1)到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn)。
客戶端要向服務(wù)端發(fā)起連接請求,首先客戶端隨機(jī)生成一個(gè)起始序列號ISN(比如是100),那客戶端向服務(wù)端發(fā)送的報(bào)文段包含SYN標(biāo)志位(也就是SYN=1),序列號seq=100。 - 第二次握手:服務(wù)器收到SYN包,必須確認(rèn)客戶端的SYN(ACK=1,ack=x+1),同時(shí)自己也發(fā)送一個(gè)SYN包(SYN=1,seq=y)給客戶端,即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)。
服務(wù)端收到客戶端發(fā)過來的報(bào)文后,發(fā)現(xiàn)SYN=1,知道這是一個(gè)連接請求,于是將客戶端的起始序列號100存起來,并且隨機(jī)生成一個(gè)服務(wù)端的起始序列號(比如是300)。然后給客戶端回復(fù)一段報(bào)文,回復(fù)報(bào)文包含SYN和ACK標(biāo)志(也就是SYN=1,ACK=1)、序列號seq=300、確認(rèn)號ack=101(客戶端發(fā)過來的序列號+1)。 - 第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ACK=1,ack=y+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成三次握手。
客戶端收到服務(wù)端的回復(fù)后發(fā)現(xiàn)ACK=1并且ack=101,于是知道服務(wù)端已經(jīng)收到了序列號為100的那段報(bào)文;同時(shí)發(fā)現(xiàn)SYN=1,知道了服務(wù)端同意了這次連接,于是就將服務(wù)端的序列號300給存下來。然后客戶端再回復(fù)一段報(bào)文給服務(wù)端,報(bào)文包含ACK標(biāo)志位(ACK=1)、ack=301(服務(wù)端序列號+1)、seq=101(第一次握手時(shí)發(fā)送報(bào)文是占據(jù)一個(gè)序列號的,所以這次seq就從101開始,需要注意的是不攜帶數(shù)據(jù)的ACK報(bào)文是不占據(jù)序列號的,所以后面第一次正式發(fā)送數(shù)據(jù)時(shí)seq還是101)。當(dāng)服務(wù)端收到報(bào)文后發(fā)現(xiàn)ACK=1并且ack=301,就知道客戶端收到序列號為300的報(bào)文了,就這樣客戶端和服務(wù)端通過TCP建立了連接。
四次揮手
四次揮手過程是用于正常關(guān)閉TCP連接的過程。
圖片
比如客戶端初始化的序列號ISA=100,服務(wù)端初始化的序列號ISA=300。TCP連接成功后客戶端總共發(fā)送了1000個(gè)字節(jié)的數(shù)據(jù),服務(wù)端在客戶端發(fā)FIN報(bào)文前總共回復(fù)了2000個(gè)字節(jié)的數(shù)據(jù)。
- 第一次揮手:客戶端發(fā)送一個(gè)FIN包,表示想要關(guān)閉TCP連接。客戶端進(jìn)入FIN_WAIT_1狀態(tài),等待服務(wù)器確認(rèn)。
當(dāng)客戶端的數(shù)據(jù)都傳輸完成后,客戶端向服務(wù)端發(fā)出連接釋放報(bào)文(當(dāng)然數(shù)據(jù)沒發(fā)完時(shí)也可以發(fā)送連接釋放報(bào)文并停止發(fā)送數(shù)據(jù)),釋放連接報(bào)文包含F(xiàn)IN標(biāo)志位(FIN=1)、序列號seq=1101(100+1+1000,其中的1是建立連接時(shí)占的一個(gè)序列號)。需要注意的是客戶端發(fā)出FIN報(bào)文段后只是不能發(fā)數(shù)據(jù)了,但是還可以正常收數(shù)據(jù);另外FIN報(bào)文段即使不攜帶數(shù)據(jù)也要占據(jù)一個(gè)序列號。 - 第二次揮手:服務(wù)器收到FIN包后,發(fā)送一個(gè)ACK包給客戶端,確認(rèn)客戶端的請求,服務(wù)器進(jìn)入CLOSE_WAIT狀態(tài)。
服務(wù)端收到客戶端發(fā)的FIN報(bào)文后給客戶端回復(fù)確認(rèn)報(bào)文,確認(rèn)報(bào)文包含ACK標(biāo)志位(ACK=1)、確認(rèn)號ack=1102(客戶端FIN報(bào)文序列號1101+1)、序列號seq=2300(300+2000)。此時(shí)服務(wù)端處于關(guān)閉等待狀態(tài),而不是立馬給客戶端發(fā)FIN報(bào)文,這個(gè)狀態(tài)還要持續(xù)一段時(shí)間,因?yàn)榉?wù)端可能還有數(shù)據(jù)沒發(fā)完。 - 第三次揮手:服務(wù)器發(fā)送一個(gè)FIN包給客戶端,表示自己想要關(guān)閉連接。服務(wù)器進(jìn)入LAST_ACK狀態(tài),等待客戶端的確認(rèn)。
服務(wù)端將最后數(shù)據(jù)(比如50個(gè)字節(jié))發(fā)送完畢后就向客戶端發(fā)出連接釋放報(bào)文,報(bào)文包含F(xiàn)IN和ACK標(biāo)志位(FIN=1,ACK=1)、確認(rèn)號和第二次揮手一樣ack=1102、序列號seq=2350(2300+50)。 - 第四次揮手:客戶端收到服務(wù)器的FIN包后,發(fā)送一個(gè)ACK包給服務(wù)器,確認(rèn)服務(wù)器的請求??蛻舳诉M(jìn)入TIME_WAIT狀態(tài),等待足夠長的時(shí)間以確保服務(wù)器收到了自己的確認(rèn)。然后客戶端進(jìn)入CLOSED狀態(tài),關(guān)閉連接。服務(wù)器收到ACK包后,進(jìn)入CLOSED狀態(tài),關(guān)閉連接。
客戶端收到服務(wù)端發(fā)的FIN報(bào)文后,向服務(wù)端發(fā)出確認(rèn)報(bào)文,確認(rèn)報(bào)文包含ACK標(biāo)志位(ACK=1)、確認(rèn)號ack=2351、序列號seq=1102。注意客戶端發(fā)出確認(rèn)報(bào)文后不是立馬釋放TCP連接,而是要經(jīng)過2MSL(最長報(bào)文段壽命的2倍時(shí)長)后才釋放TCP連接。而服務(wù)端一旦收到客戶端發(fā)出的確認(rèn)報(bào)文就會(huì)立馬釋放TCP連接,所以服務(wù)端結(jié)束TCP連接的時(shí)間要比客戶端早一些。