提起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知道客戶端請求建立連接,服務器端將標志位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,并將該資料包發送給客戶端以確認連接請求,服務器端進入SYN_RCVD狀態,
第三次握手:客戶端收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,并將該資料包發送給服務器端,服務器端檢查ack是否為K+1,ACK是否為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協議族博大而精深
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/79513.html
標籤:其他
