1. 程式人生 > >真的懂了:TCP協議中的三次握手和四次揮手(關閉連接時, 當收到對方的FIN報文時, 僅僅表示對方不在發送數據了, 但是還能接收數據, 己方也未必全部數據都發送對方了。相當於一開始還沒接上話不要緊,後來接上話以後得讓人把話講完)

真的懂了:TCP協議中的三次握手和四次揮手(關閉連接時, 當收到對方的FIN報文時, 僅僅表示對方不在發送數據了, 但是還能接收數據, 己方也未必全部數據都發送對方了。相當於一開始還沒接上話不要緊,後來接上話以後得讓人把話講完)

流程圖 .cn 服務 soc knowledge ber tcp連接 是什麽 一次

一、TCP報文格式

  下面是TCP報文格式圖:

          技術分享圖片

  (1) 序號, Seq(Sequence number), 占32位,用來標識從TCP源端向目的端發送的字節流,發起方發送數據時對此進行標記。

  (2) 確認號, Ack(Acknowledge number), 占32位, 只有ACK標誌位為1時,確認序號字段才有效,Ack=Seq+1。

  (3) 標誌位 有6種標示(SYN、ACK、PSH、RST、URG、FIN):

    ① SYN(synchronous建立聯機)

    ② ACK(acknowledgement 確認)

    ③ PSH(push傳送)

    ④ RST(reset重置)

    ⑤ URG(urgent緊急)

    ⑥ FIN(finish結束)

  註:

    ① 不要將確認號Ack(Acknowledge number) 和 標誌位中的 ACK(acknowledgement)混淆

二、三次握手

  技術分享圖片

  (1) 第一次握手: Client將標誌位SYN置為1, 隨機產生一個seq=J, 並將該數據包發送給Server, Client進入SYN_SENT狀態, 等待

         Server確認.

  (2) 第二次握手: Server收到數據包後由標誌位SYN=1知道Client請求建立連接, Server將標誌位SYN和ACK都置為1,ack=J+1,

          隨機產生一個值seq=K,並將該數據包發送給Client以確認連接請求,Server進入SYN_RECV狀態.

  (3) 第三次握手: Client收到確認後, 檢查ack是否為J+1, ACK是否為1, 如果正確則將標誌位ACK置為1,ack=K+1, 並將該數據

         包發送給Server,Server檢查ack是否為K+1, ACK是否為1, 如果正確則連接建立成功, Client和Server進入

         ESTABLISHED狀態, 完成三次握手, 隨後Client與Server之間可以開始傳輸數據了. 

  SYN攻擊:

     在三次握手過程中, Server發送SYN_ACK之後, 收到Client的ACK之前的TCP連接稱為 半連接(half-open connect), 此時

  Server處於SYN_RECV狀態,Server轉入ESTABLISHED狀態. SYN攻擊就是Client在短時間內偽造不存在的IP地址, 並向Server

  不斷的發送SYN包, Server回復確認包, 並等待Client確認, 由於源地址不存在的, 因此Server需要不斷重發直至超時, 這些偽造的

  SYN包將產時間占用未連接隊列, 導致正常的SYN請求因為隊列滿而被丟棄, 從而引起網絡堵塞甚至系統癱瘓. SYN攻擊時一種典

  型的DDOS攻擊, 檢測SYN攻擊的方式非常簡單, 即當Server上有大量半連接狀態切源IP地址是隨機的, 則可以斷定遭到SYN攻擊

  了, 使用如下命令可以讓之現行:

      #netstat -nap | grep SYN_RECV

四、四次揮手

    所謂四次揮手就是終止TCP連接, 就是要斷開一個TCP連接時, 需要客戶端和服務器總共進行四次交互。在socket編程中, 這個

  執行過程由客戶端或者服務器任意一方執行close來觸發, 下面是斷開流程圖:

    技術分享圖片

    由於TCP連接時全雙工的, 因此, 每個方向都必須要單獨進行關閉, 這一原則是當一方完成數據發送任務後, 發送一個FIN來終止

  這一方向的連接,收到一個FIN只是意味著這一方向上沒有數據流動了, 即不會再收到數據了, 但是在這個TCP連接上仍然能夠發送數

  據,直到這一方向也發送了FIN. 首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉,上圖描述的即是如此。

  (1) 第一次揮手: Client發送一個FIN, 用來關閉Client 到 Server的數據傳輸, Client進入FIN_WAIT_1狀態

  (2) 第二次揮手: Server收到FIN後, 發送一個ACK給Client, 確認序號為收到的序號+1(與SYN相同, 一個FIN占用一個序號),

          Server進入CLOSE_WAIT狀態

  (3) 第三次揮手: Server發送一個FIN後, 用來關閉Server到Client的數據傳輸, Server進入LAST_ACK狀態

  (4) 第四次揮手: Client收到FIN後, Client進入TIME_WAIT狀態, 接著發送一個ACK給Server, 確認序號為收到序號+1, Server

          進入CLOSED狀態, 完成四次揮手

四、狀態

  SYN_SENT狀態:

      當客戶端SOCKET執行CONNECT連接時,它首先發送SYN報文,因此也隨即它會進入到了SYN_SENT狀態,並等待服務

    端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文. (發送端)

  SYN_RCVD狀態: 這個狀態與SYN_SENT相呼應這個狀態表示接受到了SYN報文.

  ESTABLISHED: 表示連接已經建立了.

  CLOSE_WAIT狀態:

      發起TCP連接關閉的一方稱為client,被動關閉的一方稱為server. 被動關閉的server收到FIN後, 但未發出ACK的TCP狀態

  是CLOSE_WAIT. 出現這種狀況一般都是由於server端代碼的問題, 如果你的服務器上出現大量CLOSE_WAIT, 應該要考慮檢查代碼.

  TIME_WAIT狀態:

     表示收到了對方的FIN報文, 並發送出ACK報文, 就等2MSL後即可回到CLOSED可用狀態.

  LAST_ACK:

     表示被關閉的一方在發送FIN報文後, 最後等待對方的ACK報文. 當收到ACK報文後, 也即可以進入到CLOSED狀態了.

  CLOSED: 表示連接中斷.

五、總結

  關於三次握手與四次揮手通常都會有典型的面試題:

  (1) 三次握手是什麽或者流程? 四次握手呢? 答案前面分析就是.

  (2) 為什麽連接時是三次握手, 而關閉連接卻是四次揮手?

    這是因為服務端在LISTEN狀態下, 收到建立連接請求的SYN報文後, 把ACK和SYN放在一個報文裏發送給客戶端. 而關閉連接時,

  當收到對方的FIN報文時, 僅僅表示對方不在發送數據了, 但是還能接收數據, 己方也未必全部數據都發送對方了, 所以己方可以立即

  close, 也可以發送一些數據給對方後, 再發送FIN報文給對方來表示同意現在關閉連接, 因此, 己方ACK和FIN一般都會分開發送。

參考文章:

  http://blog.csdn.net/xifeijian/article/details/12777187

  http://www.cnblogs.com/Jessy/p/3535612.html    

  http://blog.csdn.net/renzhenhuai/article/details/12105457

http://www.cnblogs.com/jiangson/p/5980681.html

真的懂了:TCP協議中的三次握手和四次揮手(關閉連接時, 當收到對方的FIN報文時, 僅僅表示對方不在發送數據了, 但是還能接收數據, 己方也未必全部數據都發送對方了。相當於一開始還沒接上話不要緊,後來接上話以後得讓人把話講完)