目錄
1.Tcp協議介紹
1.1 Tcp協議層級
1.2 TCP協議的格式
2. 確認應答機制
2.1 確認應答
2.2 序號字段
2.3 捎帶應答
3. 流量控制
4. 三次握手 四次揮手
4.1 認識標志位
4.2 簡單認識
4.3 三次揮手
4.4 四次揮手
1.Tcp協議介紹
1.1 Tcp協議層級
計算機網絡:TCP/IP網絡協議-CSDN博客
下面是TCP/IP網絡協議族層級劃分,TCP協議位于傳輸層。其中傳輸層和網絡層都歸屬于操作系統層面。
TCP協議全稱是傳輸控制協議(Transmission Control Protocol),是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。顧名思義,Tcp協議要對數據傳輸進行控制。
- 如下圖,用戶從主機A發送消息,應用層通常需要對數據進行序列化。序列化是對某個數據結構按照特定格式組織稱一條完整數據。而反序列化是將一條數據轉按照特定格式轉換成原來對應的數據結構。
- 序列化后的數據通過write系統調用拷貝給TCP層中的發送緩沖區,每往下一層,都要加上對應的數據報頭。
- 之后,通過網絡傳輸到主機B。先從物理層開始,對數據包進行解包分用。當到主機BTCP層的接收緩沖區,就會得到對方發來的序列化數據。通過read系統調用函數,讀取緩沖區的數據,再進行反序列化,主機B的用戶就會接受到發來的消息。
TCP協議對應的文件描述符是全雙工的,既可以接收數據,也可以發送數據。因為TCP層中有兩個緩沖區。數據從TCP的發送緩沖區傳輸到網絡層,會在該數據前面加上TCP協議的報頭,下面我們來了解一下TCP協議的格式。
1.2 TCP協議的格式
-
源/目的端口號:這兩個端口號分別表示數據是從哪個進程來,到哪個進程去。它們用于識別發送方和接收方的應用程序。
-
32位序號/32位確認號:序號用于標識發送的數據段,確保數據的順序。確認號用于確認接收到的數據段的序號,確保數據的完整性。
-
4位TCP報頭長度:這個字段表示TCP頭部有多少個32位(即4字節)。因此,TCP頭部的最大長度是15 * 4 = 60字節。
-
6位標志位:這些標志位用于控制TCP連接的狀態和傳輸方式。
- URG:表示緊急指針是否有效。
- ACK:表示確認號是否有效。
- PSH:提示接收端應用程序立即從TCP緩沖區讀取數據。
- RST:對方要求重新建立連接,攜帶RST標識的稱為復位報文段。
- SYN:請求建立連接,攜帶SYN標識的稱為同步報文段。
- FIN:通知對方本端要關閉連接,攜帶FIN標識的稱為結束報文段。
-
16位窗口大小:這個字段用于流量控制,表示接收方的緩沖區大小。
-
16位校驗和:發送端填充,用于CRC校驗。接收端通過校驗和來驗證數據是否正確。校驗和不僅包含TCP首部,還包含TCP數據部分。
-
16位緊急指針:標識哪部分數據是緊急數據。
-
40字節頭部選項:這部分暫時忽略。
總的來說,TCP協議的報頭長度在20-60字節之間。
2. 確認應答機制
2.1 確認應答
確認應答機制是TCP協議保證可靠性中最重要的一環。
- 主機A向主機B發送一條消息,主機A如何保證消息被主機B接收呢?主機B會向主機A發送確認消息。那么主機B怎么保證這條確認消息被主機A接收呢?主機A也會發送一條確認消息。
- 如此循環下去,你會發現新發的消息永遠得不到確認,也就是不可靠。但是歷史消息會得到確認,所以說這里的可靠性是指對歷史消息的確認。
2.2 序號字段
可是,這么多條歷史消息,怎么保證收到的是哪一條消息。TCP將每個字節的數據進行編號,即為序列號。我們可以將tcp的接受緩沖區類比成一個大字符數組,那么每個字節的數據就有了下標,天然就有了編號。
主機A的發送緩沖區拷貝上層的數據,發送出去后,對方接受緩沖區直接一股腦接收到接收緩沖區,本質上就是拷貝數組上的數據。
上圖中還是主機A和主機B進行通信。
- 主機A發送的TCP報文中,有序號字段,表示發送數據的順序。如果主機A報文中序號字段為1000,主機B接受到該條數據,會解析報文中的序號字段。
- 之后,主機B會在組織應答報文時,將TCP報文中確認序號字段填上1001,表示1001序號之前的數據已經獲取。即確認序號字段會填寫主機收到最大序號數,并加一。
2.3 捎帶應答
張三問:“李四今天吃了什么?”。李四回答:“叉燒炒蛋飯。你呢?”。在上面這段對話中,張三向李四發起問答,李四回答后,順便向張三也發起問答。
?tcp通信類似于人類的對答機制。主機A和主機B類比于張三和李四。主機A發送一條消息給主機B,主機B接受到后,組織tcp報文,并填寫確認序號字段,同時也攜帶數據,填寫序號字段。
上圖中,左邊部分才是tcp通信的真實情況。這種機制就是捎帶應答。這也是為什么會有確認序號字段的原因。
3. 流量控制
主機A發送大量數據給主機B,主機B的接受緩沖區已經滿載了,無法接收新的數據。此時,主機B的操作系統只能丟棄新的tcp報文。不過tcp報文有超時重傳機制,超過一定時間沒收到確認應答報文,會重發tpc報文。
- 可是這些被丟棄的tcp報文經過無數個路由器,經歷千難萬險,通過網絡發送到目標主機。tcp報文不是需要保證可靠性嗎?操作系統不會做浪費時間和空間的事情。
- 主機中的接受緩沖區剩余空間大小決定能接受多少數據,所以只需要知道對方接收緩沖區剩余空間,就可以控制tcp報文攜帶的數據大小,做到流量控制。
但是任何主機如何知道目標主機的緩沖區剩余空間大小呢?tcp報文中有窗口大小字段,該字段表示本主機接受緩沖區剩余空間的大小。對方主機接受到tcp報文,解析該字段,便知道發送主機的緩沖區剩余空間大小,就可以控制發送的數據大小。
4. 三次握手 四次揮手
4.1 認識標志位
客戶端向服務端發送tcp報文,不同的tcp報文通信的功能也不相同,可能是建立連接的請求,正常數據通信請求或者斷開連接的請求。
其中ACK表示該報文有確認應答功能,SYN表示向目標主機建立連接,FIN表示要求斷開連接。
4.2 簡單認識
?在確認應答機制中,最新發出的一條消息無法保證是否被接收,但是歷史消息能保證被接收,這就是確認應答機制的核心。
三次握手一般是由客戶端發起連接請求,服務端收到連接請求后,給予確認應答,并捎帶服務端的連接請求,最后客戶端進行確認應答。
四次揮手一般是由客戶端發起斷開連接請求,服務端收到后回復。之后,再由服務端發起斷開連接請求,客戶端進行確認應答。
4.3 三次揮手
三次握手,本質上雙方各自一次請求并接收對方應答,
- 客戶端調用connect函數建立連接時,操作系統就會自動組織tcp報文,發起連接請求,此時客戶端tcp層處于SYN_SENT。
- 服務端這邊需要調用listen函數,處于監聽狀態,再調用accept函數給新連接分配新文件描述符,讓新文件描述符用于客戶端通信。此時,操作系統會發送確認應答和連接請求給對方。
- 客戶端收到后,便處于ESTABLISHED狀態。客戶端的操作系統也組織確認應答報文,發送給服務端,服務端接收到之后,也處于ESTABLISHED狀態
- 但是客戶端發出最后一次的確認應答,是最新一條消息,這是無法保證可靠性,所以說客戶端在賭最后一個ACK應答被服務端收到。
為什么要有三次握手?
- 建立雙方主機通信意識的共識
- 因為TCP是全雙工的,三次握手可以驗證全雙工通信的通暢性。
4.4 四次揮手
四次揮手中,也是雙方的一問一答。
- 先提出斷開連接請求的那一方,狀態會變成FIN_WAIT_1,接收到對方的斷開連接請求的一方,狀態會變成CLOSE_WAIT。
- 假設客戶端是先提出斷開連接的一方,那么接收到斷開連接的確認應答后,會變成TIME_WAIT狀態。服務端過一會也想斷開連接,也會發出斷開連接請求。最后都變成CLOSED狀態。
- 但是在應用層上,其實是雙方調用了close函數,關閉用于tcp通信的文件描述符。而tcp報文的組織和發送都是由操作系統自己完成的。
- 至于為什么會有TIME_WAIT狀態,先關閉那一方等待對方關閉連接請求而設置的狀態,一般是兩分鐘。
- 為什么要進行四次揮手呢?因為要關閉兩個通信的文件描述符。
不過有些人可能會問,為什么不把中間的斷開連接請求和確認斷開連接應答合并,使用捎帶應答機制,來完成揮手操作。
事實上,TCP協議確實存在通過三次通信完成連接終止的可能性。其關鍵在于能否實現"FIN-ACK捎帶應答"機制——當被動關閉方收到主動關閉方的FIN報文后,如果此時應用層已完成數據處理并立即觸發關閉流程,系統可以將ACK確認報文與己方的FIN結束報文合并發送。這種合并使得原本需要四次報文交互的過程(FIN→ACK→FIN→ACK)被優化為三次(FIN→ACK+FIN→ACK)。
但是多數情況下仍然需要完整的四次揮手流程。
最后這是雙方正常tcp通信情況。
創作充滿挑戰,但若我的文章能為你帶來一絲啟發或幫助,那便是我最大的榮幸。如果你喜歡這篇文章,請不吝點贊、評論和分享,你的支持是我繼續創作的最大動力!