重要的幾個概念:html
SYN
: 發起新的鏈接ACK
:確認序號有效。seq序號
ack序號
: 只有在ACK=1
的狀況下有效,ack序號 = seq序號+ 1FIN
: 釋放一個鏈接客戶端
發起SYN=1,表示須要新建鏈接,而且帶上隨機數seq=x (Client進入SYN_SENT狀態)服務端
在收到數據包以後,根據SYN=1知道客戶端
是但願創建新的鏈接,因此服務端發送的信息裏面SYN
和ACK
都置爲1,而且對客戶端上傳上的seq序號=x
+1==>ack=x+1
,而且帶上本身生成的隨機數seq=y
(Server進入SYN_RCVD)確認ACK是否等於1
而且確認ack是否等於x+1
,若是正確則將ACK=1,ack=y+1
(Client和Server進入ESTABLISHED)爲何要用三次握手,而不是兩次握手呢??網絡
若是客戶端發送第一次握手以後,由於網絡很差,消息在網絡中走的有點久,等到消息到達服務端的時候,消息已經失效了(可是這個時候服務端並不知曉),假設沒有第三次握手,服務端在收到消息作出響應以後,就創建起新的鏈接,一直等待客戶端發送消息,可是客戶端已經認爲失效了。這樣就會致使服務端的資源被白白浪費。採用三次握手就是爲了防止這種狀況的發生,server會由於收不到確認的報文,就知道client並無創建鏈接。這就是三次握手的做用。3d
SYN攻擊:code
在三次握手過程當中,Server發送SYN-ACK以後,收到Client的ACK以前的TCP鏈接稱爲半鏈接(half-open connect),此時Server處於SYN_RCVD狀態,當收到ACK後,Server轉入ESTABLISHED狀態。SYN攻擊就是Client在短期內僞造大量不存在的IP地址,並向Server不斷地發送SYN包,Server回覆確認包,並等待Client的確認,因爲源地址是不存在的,所以,Server須要不斷重發直至超時,這些僞造的SYN包將產時間佔用未鏈接隊列,致使正常的SYN請求由於隊列滿而被丟棄,從而引發網絡堵塞甚至系統癱瘓。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式很是簡單,即當Server上有大量半鏈接狀態且源IP地址是隨機的,則能夠判定遭到SYN攻擊了,使用以下命令可讓之現行:#netstat -nap | grep SYN_RECVcdn
客戶端
發送 FIN=1
標識須要釋放鏈接,而且帶上本身的隨機數seq=u服務端
接收到FIN
後知道客戶端要釋放鏈接,作出響應ACK=1
,並將ack=u+1
,最後帶上本身的隨機數 seq=v服務端
向客戶端發送FIN
,用來關閉服務端
到客戶端
的數據傳輸,這裏用到的ack也是=u+1
客戶端
收到FIN
後,進入TIME_WAIT狀態,並對FIN的作出應答服務端
收到應答後,進行CLOSE狀態爲何創建鏈接是三次握手,斷開鏈接確實四次揮手呢?server
由於關閉鏈接時,A向B發送FIN,僅僅表示A再也不發送數據了,可是仍是能夠接收數據,此時B也未必已經把全部數據都發送給A了,因此B能夠當即發送FIN作響應關閉,也能夠接着把未發完的數據發完了,在發送FIN。htm
爲何客戶端會在發送完最後一個ACK後,還要等待2MSL.blog
由於客戶端返回的ACK可能在網絡傳輸中丟失,服務端會超時重傳FIN,客戶端就能在這2MSL的時間內接收到這個FIN,再次作出ACK。隊列