文章目錄
- TCP協議概括
- TCP頭部格式
- TCP連接管理
- 建立連接(三次握手)
- 數據傳輸
- 確認應答機制
- 捎帶應答
- 滑動窗口
- 丟包問題
- 擁塞控制
- 延時應達
- 終止連接(四次揮手)
TCP協議概括
TCP是一個面向連接的協議,在傳輸數據之前需要建立連接,確保通信雙方的準備工作。它提供可靠的數據傳輸服務,通過確認、重傳、流量控制和擁塞控制機制,保證數據準確且按順序地到達目的地。
TCP頭部格式
源/目的端口號: 表示數據是從哪個進程來, 到哪個進程去。
32位序號: 數據段的序列號,用于重組數據流和檢測丟失數據
32位確認號:確認收到的數據段的序列號(當收到確認序列號時,可以保證的是,此序列號之前的序列號都已經處理完成,即使沒有收到對應的序列號)。
如下圖:(1-100)是客戶端發給服務器的數據段序號,101則是服務端對客戶端發送過來數據的確認(確認應答機制)。
4位TCP報頭長度: 表示該TCP頭部有多少個32位bit(有多少個4字節); 所以TCP頭部最大長度是15 (1111)* 4 = 60(注意乘4)
6位標志位:
URG: 緊急指針是否有效
ACK: 確認號是否有效
PSH: 提示接收端應用程序立刻從TCP緩沖區把數據讀走
RST: 對方要求重新建立連接; 我們把攜帶RST標識的稱為復位報文段
SYN: 請求建立連接; 我們把攜帶SYN標識的稱為同步報文段
FIN: 通知對方, 本端要關閉了, 我們稱攜帶FIN標識的為結束報文段
在每次發送報文以及應答報文時,對于以上六中的請求,會分別對對應請求的標志位的值標志位1,來表示此數據的意義!
16位窗口大小:流量控制窗口大小,接收方可以接受的最大數據量。(每次進行報文通信時,都會將自己的接受緩沖區的具體大小告訴對方,好讓對方發送我們所能接受的字節流,以防于數據過大,導致丟包問題!)
16位校驗和: 發送端填充, CRC校驗. 接收端校驗不通過, 則認為數據有問題. 此處的檢驗和不光包含TCP首部, 也包含TCP數據部分
16位緊急指針: 標識哪部分數據是緊急數據(配合標志位的URG使用)。
選項:可選字段,用于擴展TCP協議的功能
數據:實際傳輸的數據。
TCP連接管理
TCP是面向連接的協議,通信雙方在傳輸數據之前必須先建立連接。連接管理包括連接建立、數據傳輸和連接終止三個階段。
建立連接(三次握手)
TCP使用三次握手機制建立連接,確保雙方同步并準備好數據傳輸。
SYN:客戶端發送一個SYN(同步)報文段,表示請求建立連接,同時發送初始序列號。
SYN+ACK:服務器接收到SYN報文段后,發送一個SYN-ACK報文段,確認收到SYN,并發送自己的初始序列號。
ACK:客戶端接收到SYN-ACK報文段后,發送一個ACK(確認)報文段,確認收到服務器的SYN。
通過三次握手,客戶端和服務器確認彼此的存在,并交換初始序列號,準備傳輸數據。
為什么要進行三次握手?
解決SYN洪流問題!因為如果是一次或者兩次握手,一些惡意的客戶端,對服務器進行多次連接攻擊,只要服務端收到來自客戶端的連接,不論是一次還是兩次,都會直接建立連接快速消耗內存,導致服務器掛掉,而三次握手需要客戶端的再次確認返回,才會進行建立連接,雖然也會有SYN洪流問題,但要比之前的方式減少些許負擔,同時還可以最小成本的驗證全雙工,客戶端可以驗證發送以及接受正常通信,服務端也可以驗證發送以及接受的正常通信。
數據傳輸
確認應答機制
每收到一個數據段,接收方都會發送一個確認報文段(ACK),確認收到的數據段序列號。發送方如果在一定時間內沒有收到確認,則會重傳該數據段。
如上圖是一種串行發送消息,效率可見是非常慢。所以有下圖的多行發送消息,特別注意這里每次發送數據都是報頭攜帶數據的。而返回的應答ACK則只有報頭,在報頭內將ACK標志位置為1
而這樣收到的報文可能是亂序的這樣就可以靠TCP報頭的序列號進行排序,處理。
捎帶應答
對于上面的ACK應答報文,也可以被攜帶在返回數據中,例如你向服務器發問1+1等于多少?服務器會給你回應2同時報頭中ACK的標志位置為1,表示對你1+1的信息收到了。這樣就可以將兩個通信合并為一條。大大提高效率。
滑動窗口
針對確認應答機制中的多行并發消息的解決。滑動窗口的初始大小是根據接收方返回報頭數據中自己的的接受緩沖區的大小來決定的,同時也達到流量控制的目的(當然對于網絡中進行通信有多個路由器等硬件設施,具體的滑動窗口的大小會根據這些硬件設施所能接受的大小與對方接受緩沖區的大小取最小值來設定!!)
TCP使用滑動窗口機制進行流量控制,接收方根據自己的接收能力設置窗口大小,告訴發送方可以發送的最大數據量
如下圖一次性發送一個窗口內所有的內容。倘若接受到2001的確認信號,那么窗口的左坐標就會移動到2001的位置,右坐標也會相應的增加到6001
把窗口的前坐標比作win_start,結尾坐標比作win_end,具體滑動就是根據下面的公式進行更變。
丟包問題
因為有應答序號,保證次序號之前的消息都已經收到,所以1001——2000丟包,后面數據即使收到,也只會返回1001這個確認序號,經過多次重復應答,主機A就知道,1001——2001丟了,對方沒有收到,則會再次發送此數據。
這種機制被稱為 “高速重發控制”(也叫 “快重傳”)
擁塞控制
控制滑動窗口大小的另一個決定因素
TCP通過慢啟動、擁塞避免、快重傳和快恢復等算法進行擁塞控制,防止網絡過載。
慢啟動:在連接初始階段,發送方以指數增長方式增加發送窗口大小,快速探測網絡容量。
擁塞避免:當慢啟動閾值達到一定值時,發送方以線性增長方式增加發送窗口大小,避免網絡擁塞。
快重傳和快恢復:當發送方收到重復確認(ACK)時,快速重傳丟失的數據段,并進行快速恢復,減少網絡等待時間。
發送開始的時候, 定義擁塞窗口大小為1;
每次收到一個ACK應答, 擁塞窗口加1;
每次發送數據包的時候, 將擁塞窗口和接收端主機反饋的窗口大小做比較, 取較小的值作為實際發送的窗口;
像上面這樣的擁塞窗口增長速度, 是指數級別的. “慢啟動” 只是指初使時慢, 但是增長速度非常快.
為了不增長的那么快, 因此不能使擁塞窗口單純的加倍.
此處引入一個叫做慢啟動的閾值
當擁塞窗口超過這個閾值的時候, 不再按照指數方式增長, 而是按照線性方式增長
少量的丟包, 我們僅僅是觸發超時重傳; 大量的丟包, 我們就認為網絡擁塞;
當TCP通信開始后, 網絡吞吐量會逐漸上升; 隨著網絡發生擁堵, 吞吐量會立刻下降;
擁塞控制, 歸根結底是TCP協議想盡可能快的把數據傳輸給對方, 但是又要避免給網絡造成太大壓力的折中方案
延時應達
當收到多個數據請求時,接收方的接收緩沖區就會變小,此時如果對多個數據請求先來的做出應答,那么對于應答攜帶的報頭中發送給對方的可接受緩沖區的大小是非常小,會降低下一次發送的效率,所以我們引入延時應達,我們可以等一次性收到的全部數據都處理完,通過序列號的排序,僅僅應答最后一個序列號即可(因為確認序列號可以保證攜帶之前序列號的數據已經收到并處理)
具體的延時應答策略:
數量限制: 每隔N個包就應答一次;
時間限制: 超過最大延遲時間就應答一次
具體的數量和超時時間, 依操作系統不同也有差異; 一般N取2, 超時時間取200ms
終止連接(四次揮手)
TCP使用四次揮手機制終止連接,確保雙方都能夠正常結束數據傳輸。
FIN:一方(通常是客戶端)發送一個FIN(終止)報文段,表示不再發送數據,但仍然可以接收數據。
ACK:另一方(服務器)接收到FIN報文段后,發送一個ACK報文段,確認收到FIN。
FIN:服務器發送自己的FIN報文段,表示不再發送數據。
ACK:客戶端接收到FIN報文段后,發送一個ACK報文段,確認收到服務器的FIN。