目錄
深刻理解三次握手
深刻理解四次揮手
深刻理解三次握手
- 三次握手時,如果最后一個ACK包,服務器沒有收到,此時:
客戶端:認為已經建立鏈接
服務器:認為沒有建立鏈接,還在超時等待。
而此時客戶端已經開始發送數據TCP包,則服務器收到數據TCP包后丟棄,發送RST(reset)包,提示客戶端請重新建立鏈接,這個行為叫做重置。
客戶端收到RST包,關閉已經建立的鏈接,重新做三次握手。
- 為什么建立鏈接是三次握手
如果客戶端發起一次請求,服務器就建立鏈接,這樣服務器很容易遭受攻擊,因為服務器維護鏈接是有成本的,而如果客戶端無窮無盡的發送包,服務器認為這些包都可以建立鏈接,大量的維護成本足以讓服務器死機。
客戶端發送大量請求鏈接的SYN包,稱為SYN洪水攻擊,特點是只需要一臺客戶端就可以做攻擊。
而三次握手,雖然也會遭受到SYN洪水攻擊,但相比一次、兩次握手,三次握手更加可靠許多,因為服務器要求客戶端發送ACK包,收到ACK包后,服務器才會建立鏈接,三次握手下,一定是客戶端先建立鏈接,再是服務器建立鏈接,這種關系可以保證服務器不會被一臺主機做SYN洪水攻擊。
- 為什么通信前要三次握手?
1.需要保證網絡是通暢的,仔細觀察,在三次握手中,雙方都進行了一次收發操作,確認客戶端、服務器都是全雙工的。
2.確保雙方的TCP協議棧是健康的,在一次建立鏈接的過程中,客戶端發送SYN包,等待ACK,服務端也是發送SYN包,等待ACK,只不過服務器發送的ACK包做了捎帶應答,三次握手本質是四次握手捎帶成三次握手。
深刻理解四次揮手
- 四次揮手
當客戶端不想再發送數據了,就調用close接口,此時TCP協議棧刷空發送緩沖區,發送FIN報頭,并接收ACK報頭。
- 如果服務器在收到FIN報頭后,也準備關閉鏈接,則ACK+FIN做捎帶應答,只需三次揮手即可。
- 客戶端在發送FIN報頭后,就已經調用close,那么當服務器發送FIN報頭后,客戶端是怎么接收的呢
1.TCP協議棧可以調用shutdown接口,使套接字做半雙工模式,可以只關閉發送模式,保留接收。
2.實際上,調用close后還需要等待應答,這個tcp套接字的狀態為TIME_WAIT,等待FIN報頭,響應后才會關閉鏈接。
- 四次揮手的狀態
主要談TIME_WAIT,等待的時間為2個MSL,發起方一定會進入TIME_WAIT,發起方是率性完成四次揮手的。
- 四次揮手的設計中,為什么要TIME_WAIT
1.客戶端發起FIN,收到ACK,其實已經可以關閉鏈接了,但在實際網絡中,往往存在一些遺留的歷史包的問題,這些包有極小的概率會影響新鏈接的通信,而客戶端進入TIME_WAIT,可能會等到那些遺留的包,避免歷史包的影響。
2.客戶端為什么等:在前兩次揮手中,如果包出錯了,可以重發補救,因為沒有任何一方關閉了鏈接。而在后兩次揮手中,客戶端如果已經關閉鏈接了,無法保證服務器能收到ACK響應。在客戶端TIME_WAIT的過程中,可以等到服務器的FIN包,保證服務器也完成四次揮手。