了解TCP的三次握手和四次挥手
了解TCP的三次握手和四次揮手
?
一、??? TCP/IP OSI參考模型
?
了解TCP的三次握手和四次揮手,我們首先從TCP/IP OSI參考模型說起。
OSI(Open System Interconnect),即開放式系統(tǒng)互聯(lián)。OSI定義了網(wǎng)絡(luò)互連的七層框架(物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會(huì)話層、表示層、應(yīng)用層),即ISO開放互連系統(tǒng)參考模型。每一層實(shí)現(xiàn)各自的功能和協(xié)議,并完成與相鄰層的接口通信。如下圖。
?
?
由圖可知,TCP主要位于傳輸層,TCP是基于字節(jié)流的傳輸層通信協(xié)議,將上層[應(yīng)用層]的數(shù)據(jù)流分割成報(bào)文段進(jìn)行發(fā)送;
?
二、??? 三次握手
首先我們要了解為什么要進(jìn)行三次握手,目的是什么?然后握手的流程是什么樣的?以及握手過程中可能出現(xiàn)的問題。
?
1.? “三次握手”的目的:
是為了建立可靠的TCP連接,握手過程中會(huì)初始化Seq的初始值,從而保證通信的順序性,防止因網(wǎng)絡(luò)問題而亂序;
?
2.? “三次握手”的流程:
?
? ?圖片來自網(wǎng)絡(luò)
?
TCP/IP協(xié)議中,為了提供可靠的連接,采用三次握手建立一個(gè)連接;流程描述如下:
| 第一次握手:建立連接時(shí),A發(fā)送SYN包(seq=x)到B,并進(jìn)入SYN_SEND狀態(tài),等待B確認(rèn); ???????????????????? 第二次握手:B收到SYN包,必須向A返回一個(gè)ACK包(ack=x+1)確認(rèn),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=y),即SYN+ACK包,并進(jìn)入SYN_RECV狀態(tài); ? 第三次握手:A收到B的SYN+ACK包,向B發(fā)送ACK包(ack=y+1)確認(rèn),此包發(fā)送完畢,A和B進(jìn)入established狀態(tài); |
由上面流程可知,第一次seq為1,然后下一次返回的ack序號(hào)是在對(duì)方上一次的seq的基礎(chǔ)上加 +1。? ? ??
?
在“三次握手”的過程中可能出現(xiàn)風(fēng)險(xiǎn),具體描述如下:
3.? SYN FLOOD攻擊:
介紹:SYN Flood是種典型的DoS (拒絕服務(wù)) 攻擊,效果就是服務(wù)器TCP連接資源耗盡,停止響應(yīng)正常的TCP連接請(qǐng)求。
?
原因:只進(jìn)行了第二次握手,而不進(jìn)行第三次握手,此時(shí)服務(wù)器沒有收到客戶端的ACK確認(rèn);
?
后果:服務(wù)器會(huì)不斷重試到超時(shí)(5次),linux默認(rèn)是等待63秒才斷開;會(huì)把服務(wù)器的連接數(shù)耗盡,影響到正常請(qǐng)求不能處理;
?
命令查看及防護(hù):
查看linux網(wǎng)絡(luò)狀態(tài)命令:
netstat -anp |awk '{print $6}' |sort|uniq -c |sort -rn
查看是那些ip發(fā)出的SYN命令:
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
查看linux默認(rèn)的syn配置:
sysctl -a | grep _syn
>>>#
| net.ipv4.tcp_max_syn_backlog = 262144 | //是SYN隊(duì)列的長(zhǎng)度,加大長(zhǎng)度可以容納更多等待連接的網(wǎng)絡(luò)連接數(shù) |
| net.ipv4.tcp_syncookies = 1 | //是否打開SYN Cookie 功能,該功能可以防止部分SYN攻擊;默認(rèn)為0關(guān)閉,1開啟 |
| net.ipv4.tcp_synack_retries = 2 | //SYNACK(第二次握手)的重試連接次數(shù),默認(rèn)5,建議調(diào)小控制重試次數(shù) |
| net.ipv4.tcp_syn_retries = 2 | //SYN的重試連接次數(shù),默認(rèn)5,建議調(diào)小控制重試次數(shù) |
?
總結(jié):針對(duì)SYN FLOOD攻擊,最快捷的方式就是開啟SYN Cookie功能。
?
三、??? 四次揮手
我們要了解四次揮手目的是什么?為什么需要四次?然后揮手的流程是什么樣的?以及握手過程中可能出現(xiàn)的問題。
1.? “四次揮手”的目的
為了終止TCP連接。
?
2.? “四次揮手”的流程:
?
圖片來自網(wǎng)絡(luò)
?
四次揮手流程描述如下:
| 第一次揮手:A發(fā)送一個(gè)FIN(seq=x)包,ACK(ack=y)包{上圖中沒有注明]用來關(guān)閉A到B的數(shù)據(jù)傳送,A進(jìn)入FIN_WAIT_1狀態(tài); ? 第二次揮手:B收到FIN后,發(fā)送一個(gè)ACK(ack=x+1)包給A,并進(jìn)入CLOSE_WAIT狀態(tài),同時(shí)通知應(yīng)用程序,對(duì)方A要求關(guān)閉連接; ? 第三次揮手:這時(shí)B的應(yīng)用程序通知TCP可以關(guān)閉連接,則會(huì)發(fā)送一個(gè)FIN(seq=y,ack=x+1)包,用來關(guān)閉B到A的數(shù)據(jù)傳送,B進(jìn)入LAST_ACK狀態(tài); ? 第四次揮手:A收到FIN后,A進(jìn)入TIME_WAIN狀態(tài),接著返回一個(gè)ACK(ack=y+1包)給B,B進(jìn)入CLOSED狀態(tài),完成四次揮手; |
?
3.? 為什么需要“四次揮手”
因?yàn)槿p工,收發(fā)兩個(gè)方向的連接都可以獨(dú)立關(guān)閉,以避免A數(shù)據(jù)發(fā)送完畢,再向B發(fā)送FIN關(guān)閉連接,而這時(shí)B它的上層[應(yīng)用層]可能正在處理數(shù)據(jù),需要等B的[應(yīng)用層]數(shù)據(jù)處理完成后,再向主動(dòng)A發(fā)出第三次揮手。這樣就比“三次握手”多一次連接,需要四次揮手。
?
4.? TIME_WAIT狀態(tài)為什么需要等待2MSL時(shí)間?
1) 確保有足夠的時(shí)間讓對(duì)方收到ACK包;
2) 避免新舊連接混淆;
?
具體描述:
第一,假若第四次揮手的ACK報(bào)文段丟失,因而使處在LAST-ACK狀態(tài)的B收不到對(duì)方發(fā)送的最后一個(gè)ACK包。B會(huì)超時(shí)重傳這個(gè)FIN+ACK報(bào)文段,而A就能在2MSL時(shí)間內(nèi)收到這個(gè)重傳的FIN+ACK報(bào)文段。但如果A在TIME-WAIT狀態(tài)不等待一段時(shí)間,而是在發(fā)送完ACK報(bào)文段后就立即釋放連接,就無法收到B重傳的FIN+ACK報(bào)文段,因而也不會(huì)再發(fā)送一次確認(rèn)報(bào)文段。這樣,B就無法按照正常的步驟進(jìn)入CLOSED狀態(tài)。
????????????????????
第二,A在發(fā)送完ACK報(bào)文段后,再經(jīng)過2MSL時(shí)間,就可以使本連接持續(xù)的時(shí)間所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失。這樣就可以使下一個(gè)新的連接中不會(huì)出現(xiàn)這種舊的連接請(qǐng)求的報(bào)文段。
?
5.? 服務(wù)器出現(xiàn)大量的CLOSE_WAIT狀態(tài)的原因?
該問題是我們有時(shí)在使用HttpClient時(shí)偶爾會(huì)遇到的問題。
原因:對(duì)方關(guān)閉socket連接,我方忙于讀和寫,沒有及時(shí)關(guān)閉連接(方便理解:可參考“四次揮手”圖的第三次揮手,假如對(duì)方?jīng)]有返回ACK會(huì)怎么樣);
防范:
1)? ?檢查代碼,特別是釋放資源的代碼;
2)? ?檢查配置,特別是處理請(qǐng)求的線程配置;
?
四、? ?關(guān)于TCP報(bào)文頭的說明
?
?
標(biāo)識(shí)說明:
- 16位源端口號(hào)和16位目的端口號(hào):通信雙方的端口號(hào),用來標(biāo)識(shí)不同的應(yīng)用進(jìn)程。
- 32位序號(hào)和32位確認(rèn)序號(hào):使數(shù)據(jù)包按順序處理,保證連接的可靠性;
- 4位首部長(zhǎng)度/數(shù)據(jù)偏移:最大值為1111。因?yàn)門CP報(bào)頭最多60個(gè)字節(jié),但[選項(xiàng)]長(zhǎng)度不確定,如何定位到[數(shù)據(jù)]起始位置,可通過該標(biāo)識(shí)定位。
- 6位保留:為將來定義新的用途保留,現(xiàn)在一般置0。
- 6位控制位:0或1:
- 16位窗口:滑動(dòng)窗口大小,用來告知發(fā)送端接受端的緩存大小,以此控制發(fā)送端發(fā)送數(shù)據(jù)的速率,從而達(dá)到流量控制。
- 16位校驗(yàn)和:奇偶校驗(yàn)函數(shù),檢驗(yàn)范圍包括首部和數(shù)據(jù)兩部分,用來檢驗(yàn)傳輸過程中是否有誤,由發(fā)送端計(jì)算和存儲(chǔ),并由接收端進(jìn)行驗(yàn)證。
- 選項(xiàng)/填充:常見的可選項(xiàng)是MSS表示本端所能接受的最大報(bào)文段的長(zhǎng)度,在第一次握手中指明這個(gè)字段。為保證選項(xiàng)長(zhǎng)度是32的整數(shù)倍,所以填充位會(huì)加額外的零。
- 數(shù)據(jù)部分:TCP 報(bào)文段中的數(shù)據(jù)部分是可選的。在一個(gè)連接建立和一個(gè)連接終止時(shí),雙方交換的報(bào)文段僅有 TCP 首部。如果一方?jīng)]有數(shù)據(jù)要發(fā)送,也使用沒有任何數(shù)據(jù)的首部來確認(rèn)收到的數(shù)據(jù)。在處理超時(shí)的許多情況中,也會(huì)發(fā)送不帶任何數(shù)據(jù)的報(bào)文段。
?
五、? ?介紹滑動(dòng)窗口
?
1. 滑動(dòng)窗口:
告訴發(fā)送端,接收端緩存的大小,以此控制發(fā)送端發(fā)送數(shù)據(jù)的速率,從而達(dá)到控制流量;TCP的滑動(dòng)窗口的單位是字節(jié)的;
a. 保證tcp的可靠性;
b. 保證tcp的流量控制(告訴發(fā)送端另一端的緩存,防止處理不過來);
?
2. RTT和RTO概念:
RTT: 發(fā)送一個(gè)數(shù)據(jù)包到收到對(duì)應(yīng)的ACK,所花費(fèi)的時(shí)間;
RTO: 重傳時(shí)間間隔;根據(jù)RTT計(jì)算出來,當(dāng)規(guī)定時(shí)間沒有收到ACK,則重傳;
?
3. 計(jì)算過程:
?
- AdvertisedWindow[滑動(dòng)窗口] = MaxRcvBuffer[最大接收緩存] - (LastByteRcvd - LastByteRead)
- EffectiveWindow[窗口內(nèi)剩余可發(fā)送大小] = AdvertisedWindow - (LastByteSent - LastByteAcked)
?
4. TCP會(huì)話發(fā)送四種狀態(tài):
?#1:已發(fā)送并且已收到回應(yīng);#2:已發(fā)送還沒收到回應(yīng),#3:沒有發(fā)送但允許發(fā)送;#4:沒有發(fā)送且不允許發(fā)生(由于窗口大小限制);
其中:#2+#3組成為:發(fā)送窗口;
?
?
5. TCP會(huì)話接收四種狀態(tài)原理同上;
#1:已接收并且已回應(yīng);#2:已接收但未回應(yīng);#3:沒有接收但允許接收;#4:沒有發(fā)送且不允許接收(由于窗口大小限制);
其中#3為:接收窗口;
?
六、? ?抓包工具wireshark
我們通過抓包工具wireshark來加深理解”三次握手”和“四次揮手”
找一個(gè)網(wǎng)址http://www.xxxxxx.net/?(ip: xxx.xx.xx.xx)來示范:
?
1.? 握手過程:
?
?
2.? 揮手過程:
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/ylp657/p/11205495.html
總結(jié)
以上是生活随笔為你收集整理的了解TCP的三次握手和四次挥手的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 之 使用 PIL 库做图像
- 下一篇: 2019牛客暑期多校训练营(第一场) A