不得不學的 TCP三次握手和四次揮手

     

        提起TCP,它的體系太過龐大了(足以寫了一套書TCP/IP詳解卷一,卷二,卷三),以前只買了第一卷閱讀,由於我們是碼農級別的人,很難真正的研究透,就好比汽車,大大大部分人只會開,但讓他弄懂發動機原理甚至做出模型來就難了,我們關注下tcp爲什麼要三握手四揮手,這很重要(特別是java操作數據庫時印象深刻),其實其它也很重要,碼農們要是有時間和精力,可以精讀這套書,寫寫心得體會,最好是能寫個案例。

       說正題,百度百科是這樣解釋的: TCP/IP協議TCP提供一種“”可靠“”的“”面向連接“”的字節流傳輸層服務,面向連接意味着兩個使用TCP的應用(通常是一個客戶端和一個服務端)在彼此交換數據之前必須先建立一個·TCP連接。這一過程與現實場景的打電話相似,先撥號,等待對方接聽後,才能通話。

TCP 爲提供可靠性傳輸,實行“順序控制”或“重發控制”機制。此外還具備“流控制(流量控制)”、“擁塞控制”、提高網絡利用率等衆多功能,不同於UDP

TCP有以下特點:

  • TCP充分地實現了數據傳輸時各種控制功能,可以進行丟包時的重發控制,還可以對次序亂掉的分包進行順序控制;

  • 此外,TCP 作爲一種面向有連接的協議,只有在確認通信對端存在時纔會發送數據,從而可以控制通信流量的浪費;

  • 根據 TCP 的這些機制,在 IP 這種無連接的網絡上也能夠實現高可靠性的通信( 主要通過檢驗和、序列號、確認應答、重發控制、連接管理以及窗口控制等機制實現)。

它在OSI七層協議與TCP/IP四層協議的位置如下圖:

在TCP/IP協議中,TCP處在傳輸層,TCP數據被封裝在IP數據報中,如下圖:

TCP首部數據格式如下圖:

TCP首部:源端口、目標端口、序列號、確認序號、數據偏移、保留、控制位、窗口大小、校驗和、緊急指針、選項、填充。

控制位:8位。CWR、ECE、URG、ACK、PSH、RST、SYN、FIN

CWR:爲1 就通知對方已將擁塞窗口縮小

ECE:爲1 就通知對方這邊的網絡有擁塞

URG:爲1 包中有需要緊急處理的數據

ACK(Acknowledgement):爲1 確認應答的字段變爲有效

PSH(PUSH):爲1 表示要將收到的數據立刻傳給上層應用協議

RST:爲1 表示TCP連接出現異常必須要強制斷開

SYN(Synchronize Sequence Numbers):爲1 請求建立連接

FIN:爲1 請求斷開連接

seq:序列號

ack(注意和大寫的·ACK區別):Acknowledge number確認號碼

 

TCP連接是通過三次握手進行初始化的。又由於TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議,TCP是全雙工模式,所以需要四次揮手關閉連接。

 

三次握手(Three-way Handshake)(重點):

三次握手, 是指建立一個 TCP 連接時,需要客戶端和服務器總共發送3個報文。

三次握手的目的是連接服務器指定端口,建立 TCP 連接,並同步連接雙方的序列號和確認號,交換 TCP 窗口大小信息。在 socket 編程中,客戶端執行 connect() 時, 將觸發三次握手。

三次握手過程的示意圖如下:

      

圖1   三次握手建立連接

詳細說明:

次握手:客戶端將標誌位SYN置爲1,隨機產生一個值seq=J保存在TCP首部的序列號(Sequence Number)字段裏,指明客戶端打算連接的服務器的端口,並將該數據包發送給服務器端,客戶端進入SYN_SENT狀態,等待服務器端確認。

次握手:服務器端收到數據包後由標誌位SYN=1知道客戶端請求建立連接,服務器端將標誌位SYNACK都置爲1ack=J+1,隨機產生一個值seq=K,並將該數據包發送給客戶端以確認連接請求,服務器端進入SYN_RCVD狀態。

次握手:客戶端收到確認後,檢查ack是否爲J+1ACK是否爲1,如果正確則將標誌位ACK置爲1ack=K+1,並將該數據包發送給服務器端,服務器端檢查ack是否爲K+1ACK是否爲1,如果正確則連接建立成功,客戶端和服務器端進入ESTABLISHED狀態,完成三次握手,隨後客戶端與服務器端之間可以開始傳輸數據了。

 

四次揮手(重點):

四次揮手即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發。

由於TCP連接是全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務後,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味着這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉。

下面來看看四次揮手的流程圖:

圖2  tcp四次揮手

中斷連接端可以是客戶端,也可以是服務器端。

次揮手:客戶端發送一個FIN=M,用來關閉客戶端到服務器端的數據傳送,客戶端進入FIN_WAIT_1狀態。意思是說"我客戶端沒有數據要發給你了",但是如果你服務器端還有數據沒有發送完成,則不必急着關閉連接,可以繼續發送數據。

次揮手:服務器端收到FIN後,先發送ack=M+1,告訴客戶端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息。這個時候客戶端就進入FIN_WAIT_2 狀態,繼續等待服務器端的FIN報文。

次揮手:當服務器端確定數據已發送完成,則向客戶端發送FIN=N報文,告訴客戶端,好了,我這邊數據發完了,準備好關閉連接了。服務器端進入LAST_ACK狀態。

次揮手:客戶端收到FIN=N報文後,就知道可以關閉連接了,但是他還是不相信網絡,怕服務器端不知道要關閉,所以發送ack=N+1後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。服務器端收到ACK後,就知道可以斷開連接了。客戶端等待了2MSL後依然沒有收到回覆,則證明服務器端已正常關閉,那好,我客戶端也可以關閉連接了。最終完成了四次握手。

 

爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?

建立連接時因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。所以建立連接只需要三次握手。

由於TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議,TCP是全雙工模式
這就意味着,關閉連接時,當Client端發出FIN報文段時,只是表示Client端告訴Server端數據已經發送完畢了。當Server端收到FIN報文並返回ACK報文段,表示它已經知道Client端沒有數據發送了,但是Server端還是可以發送數據到Client端的,所以Server很可能並不會立即關閉SOCKET,直到Server端把數據也發送完畢。
當Server端也發送了FIN報文段時,這個時候就表示Server端也沒有數據要發送了,就會告訴Client端,我也沒有數據要發送了,之後彼此就會愉快的中斷這次TCP連接。

 

暫時就寫這麼多,以後慢慢補充,TCP/IP協議族博大而精深

 

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