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