5.1 運輸層概述
之前所介紹的計算機網絡體系結構中的物理層、數據鏈路層以及網絡層,它們共同解決了將主機通過異構網絡互聯起來所面臨的問題,實現了主機到主機的通信。
但實際上在計算機網絡中進行通信的真正實體是位於通信兩端主機中的進程。
如何為運行在不同主機上的應用進程提供直接的通信服務是運輸層的任務,運輸層協議又稱為端到端協議。
運輸層向高層用戶屏蔽了下面網絡核心的細節(如網絡拓撲、所采用的路由選擇協議等),它使應用進程看見的就好像是在兩個運輸層實體之間有一條端到端的邏輯通信信道。
根據應用需求的不同,因特網的運輸層為應用層提供了兩種不同的運輸協議,即
面向連接的TCP和無連接的UDP,這兩種協議就是本章要討論的主要內容。
5.2 端口號、復用和分用
端口號
運行在計算機.上的進程使用進程標識符PID來標志。
因特網上的計算機並不是使用統一的操作系統, 不同的操作系統(windows, Linux, Mac OS)又使用不同格式的進程標識符。
為了使運行不同操作系統的計算機的應用進程之間能夠進行網絡通信,就必須使用統一的方法對TCP/IP體系的應用進程進行標識。
TCP/IP體系的運輸層使用端口號來區分應用層的不同應用進程。
- 端口號使用16比特表示,取值范圍0~65535:
- 熟知端口號:0~1023,IANA把這些端口號指派給了TCP/IP體系中最重要的一些應用協議,例如:FTP使用21/20,HTTP使用80,DNS使用53
- 登記端口號:1024~49151,為沒有熟知端口號的應用程序使用。使用這類端口號必須在IANA按照規定的手續登記,以防止重復。例如:Microsoft RDP微軟遠程桌面使用的端口是3389
- 短暫端口號:49152~65535,留給客戶進程選擇暫時使用。當服務器進程收到客戶進程的報文時,就知道了客戶進程所使用的動態端口號。通信結束后,這個端口號可供其他客戶進程以后使用。
- 端口號只具有本地意義,即端口號只是為了標識本計算機應用層中的各進程,在因特網中不同計算機中的相同端口號是沒有聯系的。
復用與分用
發送方的復用和接收方的分用
多個進程 利用一個運輸層協議(或者稱為運輸層接口)發送數據稱為 復用
多個進程利用一個運輸層協議(或者稱為運輸層接口)接收數據稱為 分用。
運輸層使用端口號來區分不同應用進程。
TCP/IP體系的應用層常用協議所使用的運輸層熟知端口號
5.3、UDP和TCP的對比
- UDP 和 TCP 是TCP/IP體系結構運輸層中的兩個重要協議
- 使用UDP協議的通信雙方可以隨時發送數據
- 使用TCP協議的通信雙方 ,在進行通信之前,必須使用三報文握手來建立連接;數據傳輸結束后,必須使用四報文揮手來釋放連接。
正因如此,UDP支持單播、多播以及廣播,而TCP只支持單播(因為要握手揮手)
下面來看具體的使用情況:
- UDP對應用進程交下來的報文既不合並也不拆分,而是保留這些報文的邊界
換句話說,UDP是面向應用報文的
發送方
- TCP會把應用進程交付下來的數據塊看作是一連串無結構的字節流,TCP並不知道這些待傳送的字節流的含義,TCP會將他們編號,並存儲在自己發送緩存中;
- TCP會根據發送策略,提取一定量的字節構建TCP報文並發送。
接收方
- 一方面從所接受到的TCP報文段中,取出數據載荷部分並存儲在接收緩存中;一方面將接收緩存中的一些字節交付給應用進程;
- TCP不保證接收方應用進程所收到的數據塊與發送方發送的數據塊,具有對應大小的關系;
- 接收方的應用進程必須有能力識別收到的字節流,把它還原成有意義的應用層數據。
TCP是面向字節流的,這正是TCP實現可靠傳輸、流量控制、以及擁塞控制的基礎
- UDP向上層提供無連接不可靠傳輸服務
(適用於IP電話、視頻會議等實時應用) - TCP向上層提供面向連接的可靠傳輸服務
(適用於要求可靠傳輸的應用,例如文件傳輸)
再來看一下UDP與TCP的首部格式
UDP:
TCP:
總結
用戶數據報協議UDP(User Datagram Protocol)
- 無連接
- 支持一對一、一對多、多對一和多對多交互通信。
- 對應用層交付的報文直接打包,面向應用報文
- 盡最大努力交付,也就是不可靠;不使用流量控制和擁塞控制。
- 首部開銷小,僅8字節
傳輸控制協議TCP(Transmission Control Protocol)
- 面向連接
- 每一條TCP連接只能有兩個端點EP,只能是一對一通信。
- 面向字節流
- 可靠傳輸,使用流量控制和擁塞控制。
- 首部最小20字節,最大60字節
5.3 TCP的流量控制
- 一般來說,我們總是希望數據傳輸得更快一些。
- 但如果發送方把數據發送得過快,接收方就可能來不及接收,這就會造成數據的丟失。
- 所謂流量控制(flow control)就是讓發送方的發送速率不要太快,要讓接收方來得及接收。
- 利用滑動窗口機制可以很方便地在TCP連接上實現對發送方的流量控制。
- TCP接收方利用自己的接收窗口的大小來限制發送方發送窗口的大小。
- TCP發送方收到接收方的零窗口通知后,應啟動持續計時器。持續計時器超時后,向接收方發送零窗口探測報文(零窗口探測報文也有重傳計時器,不用擔心丟失)
流程見下圖:
發送窗口調控為0后,接收方調整報文若在發送過程中丟失可能導致發送方等待調控報文,接收方等待數據報文,引發死鎖局面,為打破該局面,使用計時器和零窗口探測報文:
5.4 TCP的擁塞控制
在某段時間,若對網絡中某一資源的需求超過了該資源所能提供的可用部分, 網絡性能就要變壞。這種情況就叫做擁塞(congestion)。
- 在計算機網絡中的鏈路容量(即帶寬)、 交換結點中的緩存和處理機等,都是網絡的資源。
若出現擁塞而不進行控制,整個網絡的吞吐量將隨輸入負荷的增大而下降。
擁塞控制的四種算法
- 慢開始(slow-start)
- 擁塞避免(congestion avoidance)
- 快重傳(fast retransmit)
- 快恢復(fast recovery)
下面介紹這四種擁塞控制算法的基本原理,假定如下條件:
- 數據是單方向傳送,而另一個方向只傳送確認。
- 接收方總是有足夠大的緩存空間,因而發送方發送窗口的大小由網絡的擁塞程度來決定。
- 以最大報文段MSS的個數為討論問題的單位,而不是以字節為單位。
- 發送方維護一個叫做擁塞窗口cwnd的狀態變量,其值取決於網絡的擁塞程度,並且動態變化。
- 擁塞窗口cwnd的維護原則:只要網絡沒有出現擁塞,擁塞窗口就再增大一些;但只要網絡出現擁塞, 擁塞窗口就減少一些。
- 判斷出現網絡擁塞的依據:沒有按時收到應當到達的確認報文(即發生超時重傳)。
- 發送方將擁塞窗口作為發送窗口swnd,即swnd = cwnd。
- 真正的發送窗口值 = Min(接收方窗口值,擁塞窗口值)
- 發送方還需維護一個慢開始門限ssthresh狀態變量:
- 當cwnd < ssthresh時,使用慢開始算法;
- 當cwnd > ssthresh時,停止使用慢開始算法而改用擁塞避免算法;
- 當cwnd = ssthresh時,既可使用慢開始算法,也可使用擁塞避免算法。
下面具體介紹擁塞控制的四種算法,並用擁塞窗口與傳輸輪次的坐標圖表示
傳輸輪次:
- 指發送方給接收方發送數據報文段后,接收方給發送方發發回相應的確認報文段
- 一個傳輸輪次所經歷的時間其實就是往返時間,往返時間並非是恆定的數值
- 使用傳輸輪次是為了強調把擁塞窗口所允許發送的報文段都連續發送出去,並受到了對已發送的最后一個報文段的確認
擁塞窗口:
- 它會隨網絡擁塞程度,以及所使用的擁塞控制算法動態變化
慢開始(slow-start)
- 目的:用來確定網絡的負載能力或擁塞程度。
- 思路:由小到大逐漸增大擁塞窗口數值(加倍增加,指數增加)。
- 兩個變量:
- 擁塞窗口(cwnd):初始擁塞窗口值:2 種設置方法。窗口值逐漸增大。
- 1 至 2 個最大報文段 (舊標准)
- 2 至 4 個最大報文段 (RFC 5681)
- 慢開始門限(ssthresh):防止擁塞窗口增長過大引起網絡擁塞。
- 擁塞窗口(cwnd):初始擁塞窗口值:2 種設置方法。窗口值逐漸增大。
- 擁塞窗口成倍增加,直到大於慢開始門限值,此后要改用擁塞避免算法
擁塞避免(congestion avoidance)
- 思路:讓擁塞窗口 cwnd 緩慢地增大,避免出現擁塞。每經過一個傳輸輪次,擁塞窗口 cwnd = cwnd + 1。
- 在擁塞避免階段,具有 “加法增大” (Additive Increase) 的特點。
若在傳輸過程中出現部分報文段丟失,這必然會造成發送方對這些丟失報文段的超時重傳。
若出現了重傳計時器超時,那么系統判斷網絡很可能出現了擁塞,此時:
- 將ssthresh值更新為發生擁塞時cwnd值的一半
- 將cwnd重置為1,並重新開始執行慢開始算法
注:“慢開始”是指一開始向網絡注入的報文段少,並不是指擁塞窗口cwnd增長速度慢;
“擁塞避免”並非指完全能夠避免擁塞,而是指在擁塞避免階段將擁塞窗口控制為按線性規律增長,使網絡比較不容易出現擁塞;
慢開始和擁塞避免算法是1988年提出的TCP擁塞控制算法(TCP Tahoe版本)。
- 有時,個別報文段會在網絡中丟失,但實際上網絡並未發生擁塞。
- 這將導致發送方超時重傳,並誤認為網絡發生了擁塞;
- 發送方把擁塞窗口cwnd又設置為最小值1,並錯誤地啟動慢開始算法,因而降低了傳輸效率。
1990年又增加了兩個新的擁塞控制算法(改進TCP的性能),這就是快重傳和快恢復(TCP Reno版本)。
快重傳(fast retransmit)
所謂快重傳,就是使發送方盡快進行重傳,而不是等超時重傳計時器超時再重傳。
- 要求接收方不要等待自己發送數據時才進行捎帶確認,而是要立即發送確認;
- 即使收到了失序的報文段也要立即發出對已收到的報文段的重復確認;
- 發送方一旦收到3個連續的重復確認,就將相應的報文段立即重傳,而不是等該報文段的超時重傳計時器超時再重傳。
- 對於個別丟失的報文段,發送方不會出現超時重傳,也就不會誤認為出現了擁塞(進而降低擁塞窗口cwnd為1)。使用快重傳可以使整個網絡的吞吐量提高約20%。
快恢復(fast recovery)
發送方一旦收到3個重復確認,就知道現在只是丟失了個別的報文段。於是不啟動慢開始算法,而執行快恢復算法。
- 發送方將慢開始門限ssthresh值和擁塞窗口cwnd值調整為當前窗口的一半;開始執行擁塞避免算法。
- 也有的快恢復實現是把快恢復開始時的擁塞窗口cwnd值再增大一些, 即等於新的ssthresh + 3。
- 既然發送方收到3個重復的確認,就表明有3個數據報文段已經離開了網絡
- 這3個報文段不再消耗網絡資源而是停留在接收方的接收緩存中;
- 可見現在網絡中不是堆積了報文段而是減少了3個報文段。因此可以適當把擁塞窗口擴大些。
整體算法執行過程:
5.6 TCP超時重傳時間的選擇
超時重傳時間的選擇是TCP最復雜的問題之一。
簡單來說,超時重傳時間RTO應該略大於往返時間RTT,但是由於TCP下面是復雜的互聯網,不同情況下的RTT相差很大
- 如果超時重傳時間RTO的值設置得比RTT的值小很多,這會引起報文段不必要的重傳,使網絡負荷增大
- 如果超時重傳時間RTO的值設置得遠大於RTT的值,這會使重傳時間推遲的太長,使網絡的空閑時間增大,降低傳輸效率
所以不能直接使用某次測量得到的RTT樣本來計算超時重傳時間RTO。
但是可以利用每次測量得到的RTT樣本,計算加權平均往返時間RTTs(又稱為平滑的往返時間),顯然,超時重傳時間RTO應略大於加權平均往返時間RTTs.
RFC6298建議使用下式計算超時重傳時間RTO
實際上,RTT的測量還是比較復雜的,尤其是出現超時重傳時,由於發送的是同樣的TCP報文段,那么RTT的起始時間到底是開始發送報文段時的時間還是重傳時的時間很難判斷。
針對出現超時重傳時無法測准往返時間RTT的問題,Karn提出了一個算法:
在計算加權平均往返時間RTTs時,只要報文段重傳了,就不采用其往返時間RTT樣本。也就是出現重傳時,不重新計算RTTs,進而超時重傳時間RTO也不會重新計算。
- 這又引起了新的問題。設想出現這樣的情況:報文段的時延突然增大了很多,並且之后很長一段時間都會保持這種時延。因此在原來得出的重傳時間內,不會收到確認報文段。於是就重傳報文段。但根據Karn算法,不考慮重傳的報文段的往返時間樣本。這樣,超時重傳時間就無法更新。這會導致報文段反復被重傳。
因此,要對Karn算法進行修正。方法是:報文段每重傳一次,就把超時重傳時間RTO增大一些。典型的做法是將新RTO的值取為舊RTO值的2倍。
5.7 TCP可靠傳輸的實現
TCP基於以字節為單位的滑動窗口來實現可靠傳輸。
- 發送方在未收到接收方的確認時,可將發送窗口內還未發送的數據全部發送出去;
- 接收方只接收序號落入發送窗口內的數據。
雖然發送方的發送窗口是根據接收方的接收窗口設置的,但在同一時刻,發送方的發送窗口並不總是和接收方的接收窗口一樣大。
- 網絡傳送窗口值需要經歷一定的時間滯后,並且這個時間還是不確定的。
- 發送方還可能根據網絡當時的擁塞情況適當減小自己的發送窗口尺寸。
對於不按序到達的數據應如何處理,TCP並無明確規定。
- 如果接收方把不按序到達的數據一律丟棄,那么接收窗口的管理將會比較簡單,但這樣做對網絡資源的利用不利,因為發送方會重復傳送較多的數據。
- TCP通常對不按序到達的數據是先臨時存放在接收窗口中,等到字節流中所缺少的字節收到后,再按序交付上層的應用進程。
TCP要求接收方必須有累積確認和捎帶確認機制,這樣可以減小傳輸開銷。接收方可以在合適的時候發送確認,也可以在自己有數據要發送時把確認信息順便捎帶上。
-
接收方不應過分推遲發送確認,否則會導致發送方不必要的超時重傳,這反而浪費了網絡的資源。
TCP標准規定,確認推遲的時間不應超過0.5秒。若收到一連串具有最大長度的報文段,則必須每隔一個報文段就發送一個確認[RFC 1122]。
-
捎帶確認實際上並不經常發生,因為大多數應用程序很少同時在兩個方向上發送數據。
TCP的通信是全雙工通信。通信中的每一方都在發送和接收報文段。因此,每一方都有自己的發送窗口和接收窗口。在談到這些窗口時,一定要弄清楚是哪一方的窗口。
5.8 TCP的運輸連接管理
TCP是面向連接的協議,它基於運輸連接來傳送TCP報文段。
TCP運輸連接的建立和釋放是每一次面向連接的通信中必不可少的過程。
TCP的運輸連接管理就是使運輸連接的建立和釋放都能正常地運行。
TCP的連接建立
TCP的連接建立要解決以下三個問題:
- 使TCP雙方能夠確知對方的存在;
- 使TCP雙方能夠協商一些參數(如最大窗口值、是否使用窗口擴大選項和時間戳選項以及服務質量等);
- 使TCP雙方能夠對運輸實體資源(如緩存大小、連接表中的項目等)進行分配。
TCP使用“三報文握手”建立連接
- TCP 連接的建立采用客戶服務器方式。
- 主動發起連接建立的應用進程叫做TCP客戶 (client)。
- 被動等待連接建立的應用進程叫做TCP服務器 (server)。
“握手”需要在TCP客戶端和服務器之間交換三個TCP報文段
過程:
最初兩端的TCP進程都處於關閉狀態。
- 一開始,TCP服務器進程首先創建傳輸控制塊,用來存儲TCP連接中的一些重要信息。
- 例如TCP連接表、指向發送和接收緩存的指針、指向重傳隊列的指針,當前的發送和接收序號等。
- 之后,就准備接受TCP客戶端進程的連接請求,此時TCP服務器進程就進入監聽狀態,等待TCP客戶端進程的連接請求。
TCP服務器進程是被動等待來自TCP客戶端進程的連接請求,因此成為被動打開連接。
由於TCP連接建立是由TCP客戶端主動發起的,因此稱為主動打開連接。
-
TCP客戶進程也是首先創建傳輸控制塊。
-
然后,在打算建立TCP連接時,向TCP服務器進程發送TCP連接請求報文段,並進入同步已發送狀態。
TCP連接請求報文段首部中:
- 同步位SYN被設置為1,表明這是一個TCP連接請求報文段;
- 序號字段seq被設置了一個初始值x,作為TCP客戶端進程所選擇的初始序號。
注:TCP規定SYN被設置為1的報文段不能攜帶數據,但要消耗掉一個序號。
-
TCP服務器進程收到TCP連接請求報文段后,如果同意建立連接,則向TCP客戶進程發送TCP連接請求確認報文段,並進入同步已接收狀態。
TCP連接請求確認報文段首部中:
- 同步位SYN和確認為ACK都設置為1,表明這是一個TCP連接請求確認報文段;
- 序號字段seq被設置了一個初始值y,作為TCP服務器進程所選擇的初始序號;
- 確認號字段ack的值被設置成了x+1,這是對TCP客戶進程所選擇的初始序號(seq)的確認。
注:這個報文段也不能攜帶數據,因為它是SYN被設置為1的報文段,但同樣要消耗掉一個序號。
-
TCP客戶進程收到TCP連接請求確認報文段后,還要向TCP服務器進程發送一個普通的TCP確認報文段,並進入連接已連接狀態。
普通的TCP確認報文段首部中:
- 確認位ACK被設置為1,表明這是一個普通的TCP確認報文段;
- 序號字段seq被設置為x+1,這是因為TCP客戶進程發送的第一個TCP報文段的序號為x,所以TCP客戶進程發送的第二個報文段的序號為x+1;
- 確認號字段ack被設置為y+1,這是對TCP服務器進程所選擇的初始序號的確認。
注:TCP規定普通的TCP確認報文段可以攜帶數據,但如果不攜帶數據,則不消耗序號,下次發送數據報文段序號仍是x+1。
-
TCP服務器進程收到該確認報文段后也進入連接已建立狀態
現在,TCP雙方都進入了連接已建立狀態,它們可以基於已建立好的TCP連接,進行可靠的數據傳輸。
思考:三報文握手最后一次握手能不能去掉,反正都收到服務器端的連接請求確認了,直接進入連接已建立狀態不是也可以嗎?
其實第三次握手主要是防止已失效的連接請求報文段突然又傳送到了TCP服務器,因而導致錯誤。
發送一個連接請求報文段后超時了,客戶端重傳一個連接請求,並建立連接,通信結束后釋放連接,結果好巧不巧,結束以后,之前超時的那個連接請求報文段”反復橫跳“后到達服務器端了,服務器端就同意連接,發送連接請求確認,並自己進入連接已建立狀態,一直等着客戶端和他通信,然而客戶端並不知道此時有連接建立,這樣服務器端就會白白浪費資源。
TCP的連接釋放
- TCP 連接釋放過程比較復雜。
- 數據傳輸結束后,通信的雙方都可以在數據傳送結束后發出連接釋放的通知
TCP通過“四報文揮手”來釋放連接
過程:
現在TCP客戶進程和TCP服務器進程都處於連接已建立狀態
-
假設TCP客戶進程的應用進程通知其主動關閉TCP連接,TCP客戶進程會發送TCP連接釋放報文段,並進入終止等待1狀態
TCP連接釋放報文段首部中:
- 終止位FIN和確認位ACK的值都被設置為1,表明這是一個TCP連接釋放報文段,同時也對之前收到的報文段進行確認;
- 序號seq字段的值設置為u,它等於TCP客戶進程之前已傳送過的數據的最后一個字節的序號加1;
- 確認號ack字段的值設置為v,它等於TCP客戶進程之前已收到的、數據的最后一個字節的序號加1。
請注意:TCP規定終止位FIN等於1的報文段即使不攜帶數據,也要消耗掉一個序號。
-
TCP服務器進程收到TCP連接釋放報文段后,會發送一個普通的TCP確認報文段並進入關閉等待狀態
普通的TCP確認報文段首部中:
- 確認位ACK的值被設置為1,表明這是一個普通的TCP確認報文段;
- 序號seq字段的值設置為v,它等於TCP服務器進程之前已傳送過的數據的最后一個字節的序號加1,這也與之前收到的TCP連接釋放報文段中的確認號匹配;
- 確認號ack字段的值設置為u+1,這是對TCP連接釋放報文段的確認。
TCP服務器進程應該通知高層應用進程,TCP客戶進程要斷開與自己的TCP連接。此時,從TCP客戶進程到TCP服務器進程這個方向的連接就釋放了。
這時的TCP連接屬於半關閉狀態,也就是TCP客戶進程已經沒有數據要發送了。
但如果TCP服務器進程還有數據要發送,TCP客戶進程仍要接收,也就是說從TCP服務器進程到TCP客戶進程這個方向的連接並未關閉。
- TCP客戶進程收到TCP確認報文段后就進入終止等待2狀態,等待TCP服務器進程發出的TCP連接釋放報文段。
- 若使用TCP服務器進程的應用進程已經沒有數據要發送了,應用進程就通知其TCP服務器進程釋放連接。
由於TCP連接釋放是由TCP客戶進程主動發起的,因此TCP服務器進程對TCP連接的釋放稱為被動關閉連接。
-
TCP服務器進程發送TCP連接釋放報文段並進入最后確認狀態。
該報文段首部中:
- 終止位FIN和確認位ACK的值都被設置為1,表明這是一個TCP連接釋放報文段,同時也對之前收到的報文段進行確認;
- 序號seq字段的值為w,這是因為在半關閉狀態下,TCP服務器進程可能又發送;
- 確認號ack字段的值為u+1,這是對之前收到的TCP連接釋放報文段的重復確認。
-
TCP客戶進程收到TCP連接釋放報文段后,必須針對該報文段發送普通的TCP確認報文段,之后進入時間等待狀態。
該報文段首部中:
- 確認為ACK的值被設置為1,表明這是一個普通的TCP確認報文段;
- 序號seq字段的值設置為u+1,這是因為TCP客戶進程之前發送的TCP連接釋放報文段雖然不攜帶數據,但要消耗掉一個序號;
- 確認號ack字段的值設置為w+1,這是對所收到的TCP連接釋放報文段的確認。
-
TCP服務器進程收到該報文段后就進入關閉狀態,而TCP客戶進程還要經過2倍MSL后才能進入關閉狀態。
- MSL(Maximum Segment Lifetime),最長報文段壽命,RFC793建議為2分鍾, 這時間其實有點太長了,TCP允許根據具體情況使用更小的MSL。
思考:TCP客戶進程在發送完最后一個確認報文后,為什么不直接進入關閉狀態?而是要進入時間等待狀態?
時間等待狀態以及處於該狀態2MSL時長,可以確保TCP服務器進程可以收到最后一個TCP確認報文段而進入關閉狀態。
要是客戶端發送完確定報文段后就進入關閉狀態不管事兒了,萬一確認報文段丟失了,服務器端收不到確認報文,那么超時后又會重傳連接釋放報文段,但是客戶端已經關閉了,不理服務器了,那服務器就只好一直超時重發而且還沒用。
另外,TCP客戶進程在發送完最后一個TCP確認報文段后,在經過2MSL時長,就可以使本次連接持續時間內所產生的所有報文段都從網絡中消失,這樣就可以使下一個新的TCP連接中,不會出現舊連接中的報文段。
TCP保活計時器
TCP雙方建立了連接以后,TCP客戶進程所在的主機突然出現了故障,那么TCP服務器進程以后就不能再收到TCP客戶進程發來的數據,因此,應當采取措施使TCP服務器進程不要再白白等待下去,為此引入了保活計時器。
- TCP服務器進程每收到一次TCP客戶進程的數據,就重新設置並啟動保活計時器(2小時定時)。
- 若保活計時器定時周期內未收到TCP客戶進程發來的數據,則當保活計時器到時后,TCP服務器進程就向TCP客戶進程發送一個探測報文段,以后則每隔75秒鍾發送一次。 若一連發送10個探測報文段后仍無TCP客戶進程的響應,TCP服務器進程就認為TCP客戶進程所在主機出了故障,接着就關閉這個連接。
5.9 TCP報文段的首部格式
為了實現可靠傳輸,TCP采用了面向字節流的方式。
但TCP在發送數據時,是從發送緩存取出一部分或全部字節並給其添加一個首部使之成為TCP報文段后進行發送。
- 一個TCP報文段由首部和數據載荷兩部分構成;
- TCP的全部功能都體現在它首部中各字段的作用。
下面具體說明:
-
源端口:占16比特,寫入源端口號,用來標識發送該TCP報文段的應用進程。
-
目的端口:占16比特,寫入目的端口號,用來標識接收該TCP報文段的應用進程。
-
序號seq:占32比特,取值范圍[0,2^32-1],序號增加到最后一個后,下一個序號就又回到0。用來指出本TCP報文段數據載荷的第一個字節的序號。
-
確認號ack:占32比特,取值范圍[0,2^32-1],確認號增加到最后一個后,下一個確認號就又回到0。用來指出期望收到對方下一個TCP報文段的數據載荷的第一個字節的序號,同時也是對之前收到的所有數據的確認。
- 若確認號=n,則表明到序號n-1為止的所有數據都已正確接收,期望接收序號為n的數據。
-
數據偏移:占4比特,並以4字節為單位。用來指出TCP報文段的數據載荷部分的起始處距離TCP報文段的起始處有多遠。
- 這個字段實際上是指出了TCP報文段的首部長度。
首部固定長度為20字節,因此數據偏移字段的最小值為(0101)2
首部最大長度為60字節,因此數據偏移字段的最大值為(1111)2
- 這個字段實際上是指出了TCP報文段的首部長度。
-
保留:占6比特,保留為今后使用,但目前應置為0。
-
緊急標志位URG:取值為1時緊急指針字段有效;取值為0時緊急指針字段無效。
-
確認標志位ACK:取值為1時確認號字段才有效;取值為0時確認號字段無效。
- TCP規定,在連接建立后所有傳送的TCP報文段都必須把ACK置1。
-
推送標志位PSH:接收方的TCP收到該標志位為1的報文段會盡快上交應用進程,而不必等到接收緩存都填滿后再向上交付。
-
復位標志位RST:用來復位TCP連接。
- 當RST置1時,表明TCP連接出現了異常,必須釋放連接,然后再重新建立連接。
- RST置1還可以用來拒絕一個非法的報文段或拒絕打開一個TCP連接。
-
同步標志位SYN:在TCP連接建立時用來同步序號。
-
終止標志位FIN:用來釋放TCP連接。
-
窗口:占16比特,以字節為單位。指出發送本報文段的一方的接收窗口。
- 窗口值作為接收方讓發送方設置其發送窗口的依據。(需要注意,發送窗口還取決於擁塞窗口的大小)
- 這是以接收方的接收能力來控制發送方的發送能力,也就是所謂的流量控制。
-
校驗和:占16比特,檢查范圍包括TCP報文段的首部和數據載荷兩部分。
在計算校驗和時,要在TCP報文段的前面加上12字節的偽首部。 -
緊急指針:占16比特,以字節為單位,用來指明緊急數據的長度。
- 當發送方有緊急數據時,可將緊急數據插隊到發送緩存的最前面,並立刻封裝到一個TCP報文段中進行發送。緊急指針會指出本報文段數據載荷部分包含了多長的緊急數據,緊急數據之后是普通數據。
-
選項:
- 最大報文段長度MSS選項:TCP報文段數據載荷部分的最大長度。
- 窗口擴大選項:為了擴大窗口(提高吞吐率)。
- 時間戳選項:
- 用來計算往返時間RTT
- 用於處理序號超范圍的情況,又稱為防止序號繞回PAWS.
- 選擇確認選項
-
選項:
- 最大報文段長度MSS選項:TCP報文段數據載荷部分的最大長度。
- 窗口擴大選項:為了擴大窗口(提高吞吐率)。
- 時間戳選項:
- 用來計算往返時間RTT
- 用於處理序號超范圍的情況,又稱為防止序號繞回PAWS.
- 選擇確認選項
-
填充:由於選項的長度可變,因此使用填充來確保報文段首部能被4整除
(因為數據偏移字段,也就是首部長度字段,是以4字節為單位的)