TCP和UDP都是常見的通信協(xié)議阔籽,其中TCP以可靠數(shù)據(jù)傳輸相較于UDP更加被選用喧枷。TCP協(xié)議中最基礎的應該就是三次握手和四次揮手伞辛,稍微懂TCP的應該都知道溢豆。這篇文章就簡單闡述一下握手和揮手過程币绩。
1. 三次握手
三次握手過程簡單說起來就真的很簡單蜡秽,首先是客戶端向服務端發(fā)送SYN包,服務端向客戶端發(fā)送SYN+ACK包缆镣,最后是客戶端發(fā)送ACK包給服務端芽突。更簡單說起來就是:
- 客戶端:“我的發(fā)送正常不?”(待確認客戶端發(fā)送功能正常)
- 服務端:“正常董瞻,我的發(fā)送正常不寞蚌?”(確認服務端接收正常,待確認服務端發(fā)送正常)
-
客戶端:“正常钠糊⌒樱”(確認客戶端接收正常,服務端發(fā)送正常)
TCP三次握手
專業(yè)性解釋就是:
- 第一次:客戶端發(fā)送SYN和發(fā)送一個隨機值seq=j給服務端抄伍,客戶端進入SYN_SENT狀態(tài)艘刚,待服務端確認。
- 第二次:服務端接收到SYN端請求連接截珍,服務端確認SYN攀甚,產(chǎn)生ack=j+1,并隨機產(chǎn)生一個seq=k岗喉,并將SYN+ACK包發(fā)送給客戶端確認連接秋度,服務端進入SYN_RECV狀態(tài)。
- 第三次:客戶端收到服務端發(fā)送的SYN+ACK包钱床,將ACK(ack=k+1)發(fā)送給服務端荚斯,服務端檢查ack是k+1,正確則建立連接。服務端和客戶端進入ESTABLISHED狀態(tài)鲸拥,完成三次握手開始傳輸數(shù)據(jù)拐格。
*SYN攻擊
三次握手中僧免,服務端發(fā)送SYN-ACK之后刑赶,收到客戶端的ACK,此時處于半連接狀態(tài)懂衩。這時候服務端處于SYN_RCVD狀態(tài)撞叨,當收到ACK包后轉入ESTABLISHED狀態(tài)。SYN攻擊就是在客戶端偽造大量不存在的IP地址浊洞,不斷向服務端發(fā)送SYN包牵敷,服務端收到確認的ACK包等待客戶端確認,由于IP是不存在的法希,服務端一直發(fā)送到超時枷餐。偽造的SYN包將長時間占用為連接隊列,導致正確的SYN請求被丟棄苫亦,從而導致網(wǎng)絡癱瘓毛肋。檢測方式就是看服務端有大量半連接狀態(tài)并且客戶單IP是隨機的,那么就是被攻擊了屋剑。檢測命令就是“netstat -nap | grep SYN_RECV”
2. 四次揮手
四次揮手相較于三次握手熟悉的人就沒那么多了润匙。四次揮手流程也簡單,簡單說就是:
- 客戶端:“請求斷開連接”(客戶端不發(fā)送數(shù)據(jù)了唉匾,但是可以接收)
- 服務端:“收到孕讳,準備斷開”(服務端檢查自己,如果有數(shù)據(jù)還沒有發(fā)送完成巍膘,發(fā)送剩余數(shù)據(jù))
- 服務端:“準備完成厂财,是否斷開”(如果有則將待發(fā)送數(shù)據(jù)發(fā)送完成,服務端不再發(fā)送數(shù)據(jù))
-
客戶端:“斷開”(客戶端不再接收數(shù)據(jù)峡懈,服務端接收到后不再接收數(shù)據(jù))
TCP四次揮手
專業(yè)性解釋就是:
- 第一次揮手:客戶端發(fā)送FIN=1和seq=u(已經(jīng)傳輸數(shù)據(jù)的最后一個字節(jié)的序號加一)包璃饱,然后進入FIN_WAIT_1的狀態(tài)。FIN即使無數(shù)據(jù)也要消耗一個序號逮诲。
- 第二次揮手:服務端接收到FIN包之后帜平,向客戶端發(fā)送ACK((ACK=1) + (ack=u+1) + (seq=v))包,服務端進入CLOSE_WAIT狀態(tài)梅鹦。
- 第三次揮手:客戶端進入FIN_WAIT_2狀態(tài)裆甩,服務端發(fā)送FIN包,關閉服務端和客戶端的數(shù)據(jù)傳輸齐唆,服務端進入LAST_ACK狀態(tài)嗤栓。
- 第四次揮手:客戶端收到FIN包進入TIME_WAIT狀態(tài),接著發(fā)送ACK包給服務端,序號+1茉帅,服務端進入CLOSED狀態(tài)叨叙,結束連接。
- 為什么握手三次揮手要四次堪澎?
答:因為服務端在LISTEN狀態(tài)擂错,等待客戶端連接,收到客戶端請求連接的SYN報文樱蛤,將SYN和ACK放在同一個包里發(fā)送給客戶端钮呀。關閉連接時,收到客戶頓的FIN包后昨凡,只表示自己不再發(fā)送數(shù)據(jù)但是還可以接收爽醋。服務端不一定所有數(shù)據(jù)發(fā)送完成,所以發(fā)送完成時候可以直接關閉便脊,否則需要將數(shù)據(jù)發(fā)送完成后再關閉蚂四。所以服務端的ACK和FIN包要分開發(fā)送。- 為什么TIME_WAIT需要等待2MSL(最大報文段生存時間)才CLOSE哪痰?
答:因為有可能最后一個ACK包丟失遂赠,最后的TIME_WAIT就是用來重發(fā)丟失的ACK包《视客戶端發(fā)送最后的ACK包回復解愤,但是也可能丟失,服務端如果沒收到ACK包乎莉,將不斷發(fā)送FIN送讲。所以不能立即關閉,需要確認服務端接收到了ACK包惋啃『喵蓿客戶端會設置一個定時器,等待2MSL時間边灭,如果再次收到FIN包异希,意味著服務端沒有收到ACK包,那么客戶端再次發(fā)送ACK包并重新等待2MSL時間绒瘦。如果2MSL時間結束沒有收到服務端的FIN包称簿,那么認為服務端收到了最后的ACK包,結束連接惰帽。
備注:圖片來自網(wǎng)絡