TCP結(jié)構(gòu):
SYN是同步的縮寫,SYN 段是發(fā)送到另一臺計(jì)算機(jī)的 TCP 數(shù)據(jù)包,請求在它們之間建立連接
ACK 是“確認(rèn)”的縮寫。 ACK 數(shù)據(jù)包是任何確認(rèn)收到一條消息或一系列數(shù)據(jù)包的 TCP 數(shù)據(jù)包
TCP三次握手如圖:

1.1第一次握手
客戶端給服務(wù)器發(fā)送一個SYN標(biāo)志位為1的 TCP/IP 數(shù)據(jù)包, 該包中客戶端的初始序列號(Sequence number = J)。
1.2第二次握手
服務(wù)器返回客戶端 SYN +ACK兩個標(biāo)志位都為為1的 TCP/IP 數(shù)據(jù)包,該包中服務(wù)器的初始序列號(Sequence number = K);同時使 Acknowledgment number = J + 1來表示確認(rèn)已收到客戶端的 SYN段。
1.3第三次握手
客戶端給服務(wù)器響應(yīng)一個ACK標(biāo)志位為1的 TCP/IP 數(shù)據(jù)包, 該包中使 Acknowledgment number = K + 1來表示確認(rèn)已收到服務(wù)器的 SYN段。
解釋一下 三次握手 和 四次揮手?
三次握手:

第一次:客戶端向服務(wù)器發(fā)送syn包,此時進(jìn)入[SYN_SENT]狀態(tài),等待服務(wù)器返回信息;此時服務(wù)端確認(rèn)了客戶端發(fā)送是正常的
第二次:服務(wù)器收到syn包,需要確認(rèn)客戶端的syn包,同時自己發(fā)出一個syn+ask包給客戶端;此時客戶端知道了自己發(fā)送、接收正常,客戶端也知道服務(wù)器發(fā)送接收也正常;但是服務(wù)器不知道客戶端接收是否正常,也不知道自己發(fā)送是否正常。
第三次:[客戶端]收到服務(wù)器的syn+ask包后,向服務(wù)器發(fā)送確認(rèn)包ask,此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入[ESTABLISHED](TCP連接成功)狀態(tài);雙方都知道對方發(fā)送和接收都正常。
為什么不能兩次握手:
假如A發(fā)出了一個由于網(wǎng)絡(luò)異常變成了失效的連接a;當(dāng)a到達(dá)B,那么只要B確認(rèn),新的連接就建立了。B會一直等待A發(fā)送數(shù)據(jù),這樣就造成了資源浪費(fèi)。
為什么不能四次握手:
3次就可以解決問題了,為什么要四次
TCP三次握手詳細(xì)解析過程:

1.1 第一次握手
客戶在socket() connect()后主動(active open)連接上服務(wù)器, 發(fā)送SYN ,這時客戶端的狀態(tài)是SYN_SENT
服務(wù)器在進(jìn)行socket(),bind(),listen()后等待客戶的連接,收到客戶端的 SYN 后,
1.1.1 半連接隊(duì)列(syn queue)未滿
服務(wù)器將該連接的狀態(tài)變?yōu)镾YN_RCVD, 服務(wù)器把連接信息放到半連接隊(duì)列(syn queue)里面。
1.1.2?半連接隊(duì)列(syn queue)已滿
服務(wù)器不會將該連接的狀態(tài)變?yōu)镾YN_RCVD,且將該連接丟棄(SYN flood攻擊就是利用這個原理,
對于SYN foold攻擊,應(yīng)對方法之一是使syncookies生效,將其值置1即可,路徑/proc/sys/net/ipv4/tcp_syncookies,
即使是半連接隊(duì)列syn queue已經(jīng)滿了,也可以接收正常的非惡意攻擊的客戶端的請求,
1.2 第二次握手
服務(wù)器返回SYN+ACK段給到客戶端,客戶端收到SYN+ACK段后,客戶端的狀態(tài)從SYN_SENT變?yōu)镋STABLISHED,
也即是connect()函數(shù)的返回。
1.3 第三次握手
全連接隊(duì)列(accept queue)的最大值 /proc/sys/net/core/somaxconn (默認(rèn)128)
1.3.1 全連接隊(duì)列(accept queue)未滿
服務(wù)器收到客戶端發(fā)來的ACK, 服務(wù)端該連接的狀態(tài)從SYN_RCVD變?yōu)镋STABLISHED,
然后服務(wù)器將該連接從半連接隊(duì)列(syn queue)里面移除,且將該連接的信息放到全連接隊(duì)列(accept queue)里面。
1.3.2?全連接隊(duì)列(accept queue)已滿
服務(wù)器收到客戶端發(fā)來的ACK, 不會將該連接的狀態(tài)從SYN_RCVD變?yōu)镋STABLISHED。
當(dāng)然全連接隊(duì)列(accept queue)已滿時,則根據(jù) tcp_abort_on_overflow 的值來執(zhí)行相應(yīng)動作
SYN flood攻擊
攻擊方的客戶端只發(fā)送SYN分節(jié)給服務(wù)器,然后對服務(wù)器發(fā)回來的SYN+ACK什么也不做,直接忽略掉,
不發(fā)送ACK給服務(wù)器;這樣就可以占據(jù)著服務(wù)器的半連接隊(duì)列的資源,導(dǎo)致正常的客戶端連接無法連接上服務(wù)器。
(SYN flood攻擊的方式其實(shí)也分兩種,第一種,攻擊方的客戶端一直發(fā)送SYN,對于服務(wù)器回應(yīng)的SYN+ACK什么也不做,不回應(yīng)ACK, 第二種,攻擊方的客戶端發(fā)送SYN時,將源IP改為一個虛假的IP, 然后服務(wù)器將SYN+ACK發(fā)送到虛假的IP, 這樣當(dāng)然永遠(yuǎn)也得不到ACK的回應(yīng)。)
https://blog.csdn.net/jun2016425/article/details/81506353
四次揮手:

假設(shè)Client端發(fā)起中斷連接請求,也就是發(fā)送FIN報文。
Server端接到FIN報文后,意思是說”我Client端沒有數(shù)據(jù)要發(fā)給你了”,但是如果你還有數(shù)據(jù)沒有發(fā)送完成,則不必急著關(guān)閉Socket,可以繼續(xù)發(fā)送數(shù)據(jù)。所以 Server 端會先發(fā)送ACK,”告訴Client端,你的請求我收到了,但是我還沒準(zhǔn)備好,請繼續(xù)你等我的消息”。這個時候Client端就進(jìn)入 FIN_WAIT 狀態(tài),繼續(xù)等待Server端的FIN報文。
當(dāng)Server端確定數(shù)據(jù)已發(fā)送完成,則向Client端發(fā)送FIN報文,”告訴Client端,好了,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了”。
Client端收到FIN報文后,”就知道可以關(guān)閉連接了,但是他還是不相信網(wǎng)絡(luò),怕Server端不知道要關(guān)閉,所以發(fā)送 ACK 后進(jìn)入 TIME_WAIT 狀態(tài),如果 Server 端沒有收到 ACK 則可以重傳“,Server端收到ACK后,”就知道可以斷開連接了”。
Client端等待了2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,我Client端也可以關(guān)閉連接了。Ok,TCP連接就這樣關(guān)閉了!
整個過程:
A向B發(fā)起請求,表示A沒有數(shù)據(jù)要發(fā)送了:A——>B;
B向A發(fā)送信號,確認(rèn)A的斷開請求請求:B——>A;
B向A發(fā)送信號,請求斷開連接,表示B沒有數(shù)據(jù)要發(fā)送了:B——>A;
A向B發(fā)送確認(rèn)信號,同意斷開:A——>B。
為什么2、3次揮手不能合在一次揮手中?那是因?yàn)榇藭rA雖然不再發(fā)送數(shù)據(jù)了,但是還可以接收數(shù)據(jù),B可能還有數(shù)據(jù)要發(fā)送給A,所以兩次揮手不能合并為一次。
為什么揮手次數(shù)比握手多一次? 是因?yàn)槲帐诌^程,通信只需要處理連接。而揮手過程,通信需要處理數(shù)據(jù)+連接。