1. 程式人生 > >計算機網絡--TCP三次握手和四次揮手

計算機網絡--TCP三次握手和四次揮手

int 主動 prot 序列 等我 方便 連接狀態 結點 可靠的

TCP(傳輸控制協議)

  TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基於字節流的傳輸層通信協議。通過三次握手建立連接,通訊完成時要拆除連接,由於TCP是面向連接的所以只能用於端到端的通訊。TCP提供的是一種可靠的數據流服務,采用“帶重傳的肯定確認”技術來實現傳輸的可靠性。

  TCP報文首部格式:

技術分享圖片

一、建立連接(三次握手)

  TCP連接建立過程:首先Client端發送連接請求報文,Server段接受連接後回復ACK報文,並為這次連接分配資源。Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP連接就建立了。

  

  置位概念:根據TCP的包頭字段,存在3個重要的標識ACK、SYN、FIN

  • ACK:"acknowledge"確認標誌"。
  • SYN:"synchronize"請求同步標誌,位數置1,表示建立TCP連接。
  • FIN:"Finally"結束標誌,位數置1,表示斷開TCP連接。
  • seq:"sequance"序列號。
  • ack:"acknowledge"確認號。

技術分享圖片

三次握手過程說明:
1、由客戶端發送建立TCP連接的請求報文,其中報文中包含seq序列號,是由發送端隨機生成的,並且將報文中的SYN字段置為1,表示需要建立TCP連接。(SYN=1,seq=x,x為隨機生成數值)
2、由服務端回復客戶端發送的TCP連接請求報文,其中包含seq序列號,是由回復端隨機生成的,並且將SYN置為1,而且會產生ACK字段,ACK字段數值是在客戶端發送過來的序列號seq的基礎上加1進行回復,以便客戶端收到信息時,知曉自己的TCP建立請求已得到驗證。(SYN=1,ACK=x+1,seq=y,y為隨機生成數值)這裏的ack加1可以理解為是確認和誰建立連接。


3、客戶端收到服務端發送的TCP建立驗證請求後,會使自己的序列號加1表示,並且再次回復ACK驗證請求,在服務端發過來的seq上加1進行回復。(SYN=1,ACK=y+1,seq=x+1)

  為什麽要三次揮手?

  在只有兩次“握手”的情形下,假設Client想跟Server建立連接,但是卻因為中途連接請求的數據報丟失了,故Client端不得不重新發送一遍;這個時候Server端僅收到一個連接請求,因此可以正常的建立連接。但是,有時候Client端重新發送請求不是因為數據報丟失了,而是有可能數據傳輸過程因為網絡並發量很大在某結點被阻塞了,這種情形下Server端將先後收到2次請求,並持續等待兩個Client請求向他發送數據...問題就在這裏,Cient端實際上只有一次請求,而Server端卻有2個響應,極端的情況可能由於Client端多次重新發送請求數據而導致Server端最後建立了N多個響應在等待,因而造成極大的資源浪費!所以,“三次握手”很有必要!

二、斷開連接(四次揮手)

  TCP連接斷開過程:假設Client端發起中斷連接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",但是如果你還有數據沒有發送完成,則不必急著關閉Socket,可以繼續發送數據。所以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉連接了"。Client端收到FIN報文後,"就知道可以關閉連接了,但是他還是不相信網絡,怕Server端不知道要關閉,所以發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK後,"就知道可以斷開連接了"。Client端等待了2MSL後依然沒有收到回復,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。Ok,TCP連接就這樣關閉了!

技術分享圖片

四次揮手過程說明:
1、客戶端發送斷開TCP連接請求的報文,其中報文中包含seq序列號,是由發送端隨機生成的,並且還將報文中的FIN字段置為1,表示需要斷開TCP連接。(FIN=1,seq=x,x由客戶端隨機生成)

2、服務端會回復客戶端發送的TCP斷開請求報文,其包含seq序列號,是由回復端隨機生成的,而且會產生ACK字段,ACK字段數值是在客戶端發過來的seq序列號基礎上加1進行回復,以便客戶端收到信息時,知曉自己的TCP斷開請求已經得到驗證。(FIN=1,ACK=x+1,seq=y,y由服務端隨機生成)
3、服務端在回復完客戶端的TCP斷開請求後,不會馬上進行TCP連接的斷開,服務端會先確保斷開前,所有傳輸到A的數據是否已經傳輸完畢,一旦確認傳輸數據完畢,就會將回復報文的FIN字段置1,並且產生隨機seq序列號。(FIN=1,ACK=x+1,seq=z,z由服務端隨機生成)
4、客戶端收到服務端的TCP斷開請求後,會回復服務端的斷開請求,包含隨機生成的seq字段和ACK字段,ACK字段會在服務端的TCP斷開請求的seq基礎上加1,從而完成服務端請求的驗證回復。(FIN=1,ACK=z+1,seq=h,h為客戶端隨機生成)
至此TCP斷開的4次揮手過程完畢

  為什麽要四次揮手?

  試想一下,假如現在你是客戶端你想斷開跟Server的所有連接該怎麽做?第一步,你自己先停止向Server端發送數據,並等待Server的回復。但事情還沒有完,雖然你自身不往Server發送數據了,但是因為你們之前已經建立好平等的連接了,所以此時他也有主動權向你發送數據;故Server端還得終止主動向你發送數據,並等待你的確認。其實,說白了就是保證雙方的一個合約的完整執行!

三、TCP連接中的11種狀態

技術分享圖片

1、一開始,建立連接之前服務器和客戶端的狀態都為CLOSED;
2、服務器創建socket後開始監聽,變為LISTEN狀態;
3、客戶端請求建立連接,向服務器發送SYN報文,客戶端的狀態變味SYN_SENT;
4、服務器收到客戶端的報文後向客戶端發送ACK和SYN報文,此時服務器的狀態變為SYN_RCVD;
5、然後,客戶端收到ACK、SYN,就向服務器發送ACK,客戶端狀態變為ESTABLISHED;
6、服務器端收到客戶端的ACK後變為ESTABLISHED。此時3次握手完成,連接建立!

技術分享圖片

由於TCP連接是全雙工的,斷開連接會比建立連接麻煩一點點。
1、客戶端先向服務器發送FIN報文,請求斷開連接,其狀態變為FIN_WAIT1;
2、服務器收到FIN後向客戶端發送ACK,服務器的狀態圍邊CLOSE_WAIT;
3、客戶端收到ACK後就進入FIN_WAIT2狀態,此時連接已經斷開了一半了。如果服務器還有數據要發送給客戶端,就會繼續發送;
4、直到發完數據,就會發送FIN報文,此時服務器進入LAST_ACK狀態;
5、客戶端收到服務器的FIN後,馬上發送ACK給服務器,此時客戶端進入TIME_WAIT狀態;
6、再過了2MSL長的時間後進入CLOSED狀態。服務器收到客戶端的ACK就進入CLOSED狀態。
至此,還有一個狀態沒有出來:CLOSING狀態。
CLOSING狀態表示:
客戶端發送了FIN,但是沒有收到服務器的ACK,卻收到了服務器的FIN,這種情況發生在服務器發送的ACK丟包的時候,因為網絡傳輸有時會有意外。

  • LISTEN:等待從任何遠端TCP 和端口的連接請求。
  • SYN_SENT:發送完一個連接請求後等待一個匹配的連接請求。
  • SYN_RECEIVED:發送連接請求並且接收到匹配的連接請求以後等待連接請求確認。
  • ESTABLISHED:表示一個打開的連接,接收到的數據可以被投遞給用戶。連接的數據傳輸階段的正常狀態。
  • FIN_WAIT_1:等待遠端TCP 的連接終止請求,或者等待之前發送的連接終止請求的確認。
  • FIN_WAIT_2:等待遠端TCP 的連接終止請求。
  • CLOSE_WAIT等待本地用戶的連接終止請求
  • CLOSING等待遠端TCP 的連接終止請求確認。
  • LAST_ACK:等待先前發送給遠端TCP 的連接終止請求的確認(包括它字節的連接終止請求的確認)
  • TIME_WAIT:等待足夠的時間過去以確保遠端TCP 接收到它的連接終止請求的確認。
  • TIME_WAIT 兩個存在的理由1.可靠的實現tcp全雙工連接的終止;2.允許老的重復分節在網絡中消逝。
  • CLOSED:不在連接狀態(這是為了方便描述假想的狀態,實際不存在)。

參考博客:http://blog.51cto.com/jinlong/2065461

計算機網絡--TCP三次握手和四次揮手