為什麼UDP需要有長度欄位,而TCP不需要長度欄位呢?


TCP像一輛超載的客車,裝的人太多,容納不了一個長度欄位,但接收端可以隱含計算出。

UDP轎車很空,正好剩個位子容納UDP長度欄位,無需隱含計算,省點事,況且那兩個位元組不放長度欄位,放點啥好呢?

一端發送的協議報文,另外一端一定要有方法知道協議報文的長度,如果沒有方法知道,那這個協議一定是一個假的協議。

TCP
儘管TCP沒有一個長度欄位,來明確自己報文的長度,但是並不意味著接收端不需要知道TCP報文的長度,否則,TCP如何計算自己的checksum? 畢竟TCP的checksum需要將TCP報文長度也包括在內。

那TCP是如何計算的?
IP報文 = IP Header + IP Option/Padding + TCP報文

TCP報文長度 = IP報文長度 - IP Header長度- IP Option/Padding長度

IP報文長度已知,(IP Header /Option/Padding)長度 已知,所以TCP報文長度,接收端一定可以計算出。

TCP報文 = TCP Header + TCP Option/Padding + TCP Payload

TCP Header = 20

TCP Option/Padding = Data Offset * 4 -20

Data Offset在TCP報文頭裡顯示已知,所以接收端可以計算出TCP Option/Padding 的長度。

TCP Payload長度
= TCP報文- TCP Header - TCP Option/Padding
= TCP報文 - 20 -(Data Offset * 4 -20 )
= TCP報文 - Data Offset * 4
= IP報文長度 - (IP Header /Option/Padding)長度 - Data Offset * 4

綜上所述,接收端可以隱含地計算出上述任何欄位,其中還包括IP Padding 、TCP Padding 的填充長度。

退一步講,如果接收端不知道填充物的長度,如何剝掉填充物?


感覺這個問題要被帶偏,再多說幾句。作為一個搬運工,搬運經典裡面的一段話 Steven,W.R. &<TCP/IP Illustrated Volume 1 &>

翻譯一下:UDP length欄位是冗餘的,它等於IP total length 減去IP header。

兩個誤區:

誤區一:IP Fragment使得IP header里的length表示每一段長度,UDP header里的length表示總長度。但是數據到了UDP這一層,肯定是reassemble完了啊。難道協議棧傻到不能通過reassemble的過程獲取到IP報文的總長度,進而通過IP報文總長度獲得UDP長度嗎?

誤區二:協議是分層的,每一層都要有自己的長度。的確有一些4-7層協議頭有自己的length欄位。但是不能說所有都有,例如BGP header就有length,DHCP header就沒有length。

以下原回答:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

先來看IP header

我們在這裡有一個長度「Total Length」。

再來看在IP報文裡面的TCP header:

TCP Data的長度= IP總長度 - IP Header長度 - TCP Header長度。

因此,TCP程序在處理過程中,不需要長度也能完成工作。

那問題來了,UDP為什麼需要長度欄位?

先看看IP報文裡面的UDP header

貌似也可以通過 「IP總長度 - IP Header長度 - UDP Header長度」 得到啊。

對,是可以。

那UDP長度有什麼意義?實際上沒什麼意思。但是如果不認真填寫UDP Header裡面的Length的話,一些應用程序可能還會報錯,因為你不知道應用程序究竟是從IP Header來獲取長度還是從UDP Header來獲取長度。所以說,在UDP報文裡面,有兩個攜帶重複信息的長度欄位。

為什麼會這樣?不知道。有可能是UDP和IP協議並行發展的結果。或者說,UDP並不是等IP完全佔領主導地位之後才開發的協議。

UDP難道就不思進取嗎?在04年的UDP lite協議里,實際上UDP Header裡面的Length欄位已經變了,變成了參與計算校驗和的位元組數。在這個協議裡面,UDP的數據長度就是從IP Header計算而來。

The Lightweight User Datagram Protocol (UDP-Lite)


用簡單來講的話就是:

tcp是流式傳輸協議,並不關心單次傳輸多少數據,實際上由於網路設備的影響,也會發生將一次tcp傳輸拆解為多次,或者多次tcp傳輸合併為一次的情況(粘包),所以在tcp層面上長度是沒有意義的。

這個問題是個好問題,我覺得產生疑惑的根本原因是沒有理解協議是分層的。


UDP沒有長度欄位會導致報文並發大的時候組裝錯誤,進程socket在取報文時可能把兩條報文視為一條。TCP頭部有標誌位,不會有這個問題


印象中《計算機網路》里提到過UDP報頭設計時發現有一些空間多餘,同時帶有的UDP長度信息確實沒有也可以。但是為了網路設備硬體設計和處理方便,報頭長度需要是4位元組的整數倍。經過各種權衡就加上了。


udp任何欄位設計,當時都是有考慮的,絕不會浪費任何帶寬資源。雖然在正常情況下,udp length 是多餘。但是udp設計length 時候,是考慮ip分片的問題,為了分片後能夠知道上層udp長度。假如一個udp包文2000,被分為兩個ip fragment 包,一個1500,1個500。udp頭的信息都在第一個,如果udp不帶length ,那麼上面應用層無法知道這個udp包文是否完整。同樣的情況,對tcp沒用,因為tcp是stream機制


推薦閱讀:

如何通俗地解釋一下 TCP/UDP 協議和 HTTP、FTP、SMTP 等協議之間的區別?
為什麼很多人覺得計算機專業的會修電腦?
tcp中兩台設備在同時建立連接時,為什麼需兩次發送自己的SYN?
是不是清華北大的大多數基礎學科的本科生,研究生都學了CS?,為什麼?
你讀過哪些深入淺出的(技術)書籍?

TAG:計算機網路 | 計算機科學 | TCPIP |