TCP 三次握手 與 四次揮手

YXi發表於2019-07-12

TCP 三次握手

所謂三次握手(Three-way Handshake),是指建立一個TCP連線時,需要客戶端和伺服器總共傳送3個包,那麼為什麼在TCP建立連線時是三次握手,而不是兩次或四次? TCP名為傳輸控制協議,是一種可靠的傳輸層協議。(原則上任何資料傳輸都無法確保絕對可靠,三次握手只是確保可靠的基本需要)


舉個例子,平常和女朋友打電話的時候(雖然我現在沒有女朋友@_@)

圖片載入失敗!
對應客戶端與伺服器之間的通訊
圖片載入失敗!

  • 第一次握手
    客戶端傳送syn包(syn=x)的資料包到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
  • 第二次握手
    伺服器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也傳送一個SYN包(syn=y),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
  • 第三次握手
    客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=y+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。

注:握手過程中傳送的包裡不包含資料,三次握手完畢後,客戶端與伺服器才正式開始傳送資料。理想狀態下,TCP連線一旦建立,在通訊雙方中的任何一方主動關閉連線之前,TCP連線都將被一直保持下去。


位碼即TCP標誌位:

  • SYN(synchronous建立聯機)
  • ACK(acknowledgement 確認)
  • PSH(push傳送)
  • FIN(finish結束)
  • RST(reset重置)
  • URG(urgent緊急)
  • Sequence number(seq 順序號碼)
  • Acknowledge number(ack 確認號碼)

TCP 四次揮手

TCP的連線的拆除需要傳送四個包,因此稱為四次揮手(four-way handshake)。客戶端或伺服器均可主動發起揮手動作,在socket程式設計中,任何一方執行close()操作即可產生揮手操作。


舉個例子,和女朋友分手的時候(分手是件痛苦的事情,所以雙方儘量多些包容,少些爭吵,不要輕易說分手,畢竟在一起不容易)

圖片載入失敗!
   對應客戶端與伺服器之間的通訊  
圖片載入失敗!
  

  • 第一次揮手   主動關閉方傳送一個FIN,用來關閉主動方到被動關閉方的資料傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發資料了(當然,在fin包之前傳送出去的資料,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些資料),但是,此時主動關閉方還可以接受資料。  

  • 第二次揮手   被動關閉方收到FIN包後,傳送一個ACK給對方,確認序號為收到序號+1(與SYN相同,一個FIN佔用一個序號, SYN 和 FIN 都有seq序號)。  

  • 第三次揮手   被動關閉方傳送一個FIN,用來關閉被動關閉方到主動關閉方的資料傳送,也就是告訴主動關閉方,我的資料也傳送完了,不會再給你發資料了。  

  • 第四次揮手   主動關閉方收到FIN後,傳送一個ACK給被動關閉方,確認序號為收到序號+1,至此,完成四次揮手。

注:任何一方(客戶端或伺服器)都可以選擇主動關閉,在雙方還沒有完全確定關閉連線時,還有可能存在沒有傳送完的資料


狀態說明:

  • CLOSED: 這個表示初始狀態。
  • LISTEN(伺服器): 表示伺服器端的某個SOCKET處於監聽狀態,可以接受連線了。
  • ESTABLISHED:表示連線已經建立了。
  • SOCKET:請自行百度

為什麼建立連線協議是三次握手,而關閉連線卻是四次握手呢?

這是因為服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裡來傳送。

當關閉連線時,當收到對方的FIN報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部傳送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要傳送一些資料給對方之後,再傳送FIN報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ACK報文和FIN報文多數情況下都是分開傳送的。


^_<

相關文章