【Linux網絡編程】TCP的三次握手、四次揮手

TCP是傳輸層的主機對主機控制協議,提供可靠的連接服務,採用三次握手確認建立一個連接。
三次握手

三次握手是倆臺主機建立連接的過程,建立之前的初始狀態是:client處於connect狀態,server處於listen的狀態。

  • 第一次握手:client主動發起SYN(syn = x)報文 ,此時client進入SYN_SENT狀態,等待server確認。
  • 第二次握手:server收到SYN報文後對其進行確認(ack = x + 1),併發送自己的SYN報文(syn =y),此時server進去了SYN_RECV狀態。
  • 第三次握手:cliet收到server的SYN+ACK包,向服務器發送確認包ACK(ack = y + 1 ),此包發送完畢,client&server都進入ESTABLISHED狀態,完成三次握手。

————————————————————————————————————

四次揮手

四次揮手是倆臺主機斷開連接的過程,斷開連接之前,倆臺主機進行數據交互。客戶端執行到close()時,發生四次揮手過程。

  • 第一次揮手:client向server發送請求斷開連接的FIN(seq = x +2)報文,用來關閉client到server的數據傳送,也就是client告訴server:我已經不會再給你發數據了(當然,在FIN報文之前發送出去的數據,如果沒有收到對應的ack確認報文,client依然會重發這些數據)但是,此時client還可以接受數據(TCP是全雙工通信)。
  • 第二次揮手:server收到client的請求斷開連接的FIN報文後,發送ACK(ack = x + 3)進行確認,此時server進入CLOSE_WAIT狀態。client進入FIN_WAIT2狀態。
  • 第三次揮手:server向client發送自己的FIN報文(seq = y + 1),此時,server進入LAST_ACK狀態。
  • 第四次揮手:client收到server發送的FIN報文後,求其發送ACK(ack = y + 2)進行最後的確認,此時client進入到CLOSE_WAIT狀態。

三次握手,四次揮手示意圖如下:
在這裏插入圖片描述

三次揮手哪個階段容易出現攻擊?

SYN_FLOOD攻擊出現在第二階段,客戶端僞造大量的第一次連接SYN同步報文,使得服務器耗費資源去維護客戶端信息,並進行確認,短時間內大量的SYN報文湧向服務器,造成服務器資源被耗盡,最終導致正常的客戶段得不到響應而失敗。

爲什麼要三次握手,倆次握手可以嗎?
顯然是不可以的,下面用反證法解釋其不可以的緣由:

謝希仁版《計算機網絡》描述了這樣一個例子:“已失效的連接請求報文段”的產生在
這樣一種情況下:client 發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達server。本來這是一個早已失效的報文段。但 server 收到此失效的連接請求報文段後,就誤認爲是 client 再次發出的一個新的連接請求。於是就向 client 發出確認報文段,同意建立連接。假設不採 用“三次握手”,那麼只要 server發出確認,新的連接就建立了。由於現在 client 並沒有發出建立連接的請求,因此不會理睬 server 的確認,也不會向 server發送數據。但 server卻以爲新的運輸連接已經建立,並一直等待 client 發來數據。這樣,server 的很多資源就白白浪費掉了。採用“三次握手”的方法可以防止上述現象發生。例如剛纔那種情況,client 不會向 server 的確認發出確認。server 由於收不到確認,就知道 client 並沒有要求建立連接。”。主要目的防止 server端一直等待,浪費資源。

TIME_WAIT存在的意義?
TIME_WAIT 狀態是:主動關閉方收到被動關閉方的 FIN 報文段並且將 ACK 報文
段發出後的一種狀態。

  • 保證遲來的報文段能被識別並丟棄。
  • 保證可靠的終止 TCP 連接。保證對端能收到最後的一個 ACK,如果 ACK 丟失,在TIME_WAIT狀態本端還可以接受到對端重傳的FIN報文段並重新發送ACK。 所以 TIME_WAIT 的存在時間爲 2MSL。

TIME_WAIT 和 CLOSE_WAIT 有什麼區別?

  • CLOSE_WAIT 是被動關閉方在接收到主動關閉方的關閉請求(FIN 報文段)並且將 ACK發送出去後所處的狀態,這種狀態表示:收到了主動關閉方的關閉請求,但是本端還沒有完成工作,還未關閉。
  • TIME_WAIT 狀態是主動關閉的一端在本端已經關閉的前期下,收到對端的關閉請 求(FIN 報文段)並且將 ACK發送出去後所處的狀態,這種狀態表示:雙方都已經完成工作,只是爲了確保遲來的數據報能被是被並丟棄,可靠的終止 TCP 連接。

TCP的報頭是怎樣的?
圖片內容來源於《Linux高性能服務器編程》

32位序號( seq) :一次TCP通信(從TCP連接建立到斷開)過程中某一個傳輸方向上的字節流的每個字節的編號。假設主機A和主機B進行TCP通信,A發送給B的第-一個TCP報文段中,序號值被系統初始化爲某個隨機值ISN (Initial SequenceNumber,初始序號值)。那麼在該傳輸方向上(從A到B),後續的TCP報文段中序號值將被系統設置成ISN加上該報文段所攜帶數據的第一個字節在整個字節流中的偏移。例如,某個TCP報文段傳送的數據是字節流中的第1025 ~ 2048 字節,那麼該報文段的號值就是ISN+1025. 另外-一個傳輸方向(從B到A)的TCP報文段的序號值也具有相同的含義。
32位確認號(ACK) :用作對另- .方發送來的TCP報文段的響應。其值是收到的TCP報文段的序號值加1.假設主機A和主機B進行TCP通信,那麼A發送出的TCP報文段不僅攜帶自己的序號,而且包含對B發送來的TCP報文段的確認號。反之,B發送出的TCP報文段也同時攜帶自己的序號和對A發送來的報文段的確認號。
四位頭部長度:15個4字節,最大60個字節,固定部分20個字節,選項部分最多40個字節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章