1、TCP三向交握
1.1TCP首部解析圖和TCP三次連接配接首部内容變化圖

首部内容說明:重要的内容加粗
(1)序号:Seq序号,占32位,用來辨別從TCP源端向目的端發送的位元組流,發起方發送資料時對此進行标記。
(2)确認序号:Ack序号,占32位,隻有ACK标志位為1時,确認序号字段才有效,Ack=Seq+1。
(3)标志位:共6個,即URG、ACK、PSH、RST、SYN、FIN等,具體含義如下:
(A)URG:緊急指針(urgent pointer)有效。
(B)ACK:确認序号有效。
(C)PSH:接收方應該盡快将這個封包交給應用層。
(D)RST:重置連接配接。
(E)SYN:發起一個新連接配接。
(F)FIN:釋放一個連接配接。
注意:
(A)不要将确認序号Ack(代表确認号序号下面那個内容,圖一中的201和501)與标志位中的ACK搞混了。
(B)确認方Ack=發起方Req+1,兩端配對。
1.2 三次握手對應首部變化
- 第一次握手:序号:X;SYN标志位:1;
- 第二次握手:序号:Y;确認号:X+1;SYN标志位:1;ACK标志位:1;
- 第三次握手:序号:Z;确認号:Y+1;ACK标志位:1;
1.3 為什麼是三次握手而不是兩次?知其然更要知其是以然
- 傳統意義上解釋:防止已失效的連接配接請求又傳送到伺服器端,因而産生錯誤
根本性探究:為了實作可靠資料傳輸, TCP 協定的通信雙方, 都必須維護一個序列号, 以辨別發送出去的資料包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方互相告知序列号起始值, 并确認對方已經收到了序列号起始值的必經步驟。如果隻是兩次握手, 至多隻有連接配接發起方的起始序列号能被确認, 另一方選擇的序列号則得不到确認。我們可以通過圖一看出ACK代表着确認,如果兩次的話很清晰的能夠看出:用戶端能夠ACK服務端的資訊,但是服務端無法确認用戶端是否已經收到了資訊,進而導緻了問題1⃣️的答案。原文部落格:https://blog.csdn.net/lengxiao1993/article/details/82771768
2、TCP四次揮手過程
2.1 TCP四次揮手流程圖
流程解析:
1)假設Client端發起中斷請求,也就是發送FIN封包。Server端接到FIN封包後,意思是說“我client端要發給你了”,但是如果你還沒有資料要發送完成,則不必急着關閉Socket,可以繼續發送資料。是以是以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息"。這個時候Client端就進入FIN_WAIT狀态,繼續等待Server端的FIN封包。
2)當Server端确定資料已發送完成,則向Client端發送FIN封包,"告訴Client端,好了,我這邊資料發完了,準備好關閉連接配接了"。
3)Client端收到FIN封包後,"就知道可以關閉連接配接了,但是他還是不相信網絡,怕Server端不知道要關閉,是以發送ACK後進入TIME_WAIT狀态,如果Server端沒有收到ACK則可以重傳。“,
4)Server端收到ACK後,"就知道可以斷開連接配接了"。Client端等待了2MSL後依然沒有收到回複,則證明Server端已正常關閉,那好,我Client端也可以關閉連接配接了。Ok,TCP連接配接就這樣關閉了!
注意:在TIME_WAIT狀态中,如果TCP client端最後一次發送的ACK丢失了,它将重新發送。TIME_WAIT狀态中所需要的時間是依賴于實作方法的。典型的值為30秒、1分鐘和2分鐘。等待之後連接配接正式關閉,并且所有的資源(包括端口号)都被釋放
2.2為什麼連接配接是三次握手,關閉是四次握手
因為當Server端收到Client端的SYN連接配接請求封包後,可以直接發送SYN+ACK封包。其中ACK封包是用來應答的,SYN封包是用來同步的。但是關閉連接配接時,當Server端收到FIN封包時,很可能并不會立即關閉SOCKET,是以隻能先回複一個ACK封包,告訴Client端,"你發的FIN封包我收到了"。隻有等到我Server端所有的封包都發送完了,我才能發送FIN封包,是以不能一起發送。故需要四步握手。
2.3為什麼TIME_WAIT狀态需要經過2MSL(最大封包段生存時間)才能傳回到CLOSE狀态?
原因一:保證TCP全雙工連接配接的可靠釋放
假設場景為用戶端主動向伺服器發起斷開連接配接,假如在主動方(用戶端)最後一次發送的ACK在網絡中丢失,根據TCP的逾時重傳機制,被動方(伺服器)需要重新向用戶端發送FIN+ACK,在FIN未達到之前,必須維護這條連接配接;并且要接收到用戶端發出的ACK确認後才能終止連接配接;如果直接在重傳的FIN到達之前而關閉連接配接,當FIN到達後會促使用戶端TCP傳輸層發送RST重建立立連接配接,而本質上這是一個正常斷開連接配接的過程。
4次握手的最後一個ACK是是由主動關閉方發送出去的,若這個ACK丢失,被動關閉方會再次發一個FIN過來;若主動關閉方能夠保持一個2MSL的TIME_WAIT狀态,則有更大的機會讓丢失的ACK被再次發送出去。
原因二:為了使就得資料包在網絡中因過期而失效
為什麼是兩個2MSL的原因:如果不到2MSL就斷開連接配接,新連接配接又以舊連接配接相同的端口和ip連接配接伺服器,就連接配接的重複資料報到達又會幹擾第二個連接配接;2MSL(封包在網絡最大生存時間)在發送完最後一個ACK封包段後,再經過實踐2MSL,就可以使本連接配接持續的時間内所産生的所有封包段,都從網絡中消失。這樣就可以使下一個新的連接配接中不會出現這種就得連接配接請求封包段。
3、SYN攻擊
Syn攻擊就是用戶端 在短時間内僞造大量不存在的IP位址,向伺服器不斷地發送syn包,伺服器回複确認包,并等待客戶的确認,由于源位址是不存在的,伺服器需要不斷的重發直至逾時,這些僞造的SYN包将長時間占用未連接配接隊列,正常的SYN請求被丢棄,目标系統運作緩慢,嚴重者引起網絡堵塞甚至系統癱瘓。
Syn攻擊是一個典型的DDOS攻擊。檢測SYN攻擊非常的友善,當你在伺服器上看到大量的半連接配接狀态時,特别是源IP位址是随機的,基本上可以斷定這是一次SYN攻擊.在Linux下可以如下指令檢測是否被Syn攻擊
netstat -n -p TCP | grep SYN_RECV
一般較新的TCP/IP協定棧都對這一過程進行修正來防範Syn攻擊,修改tcp協定實作。主要方法有SynAttackProtect保護機制、SYN cookies技術、增加最大半連接配接和縮短逾時時間等.但是不能完全防範syn攻擊。