由於UDP協議傳輸數據的特性,面向無連接的。通俗的講客戶端發送一包數據給服務端,發送完就不管了,不管它是否到達,或者丟了。這樣就不用管分包的問題了,因為如果像tcp那邊分包,是保證不了順序的,這樣會有很多其他的問題。所以如果需要用UDP一次性發送很多數據,需要在上層做很多邏輯,保證數據的順序,這樣也就比較麻煩了。
前戲
進行UDP編程的時候,我們很容易會問自己問題,一次發送多少bytes好?
of course,這個沒有標準答案,相對於不同的系統,不同的要求,其得到的答案也是大不一樣的,我這裡僅對像QQ這樣一類的及時聊天消息傳輸的情況作分析,對於其他情況,你或許也能得到一點幫助。
網絡原理
首先,我們知道,TCP/IP通常被認為是一個五層協議系統:包括物理層,數據鏈路層、網絡層、運輸層、應用層 。UDP屬於運輸層,下面我們由下至上一步一步來看。
結論1:局域網環境下,建議將UDP數據控制在1472字節以下,為什麼控制在這麼個奇葩的數字字節一下?我們慢慢分析下。
我們都知道,以太網(Ethernet)數據幀的長度必須在46-1500字節之間,這是由以太網的物理特性決定的,這個1500字節被稱為鏈路層的MTU(最大傳輸單元)。但這並不是指鏈路層的長度被限制在1500字節,其實這這個MTU指的是鏈路層的數據區,並不包括鏈路層的首部和尾部的18個字節。連路層的數據區通常情況下就是IP數據報了。所以,事實上這個1500字節就是網絡層IP數據報的長度限制。因為IP數據報的首部為20字節,所以IP數據報的數據區長度最大為1480字節。而這個1480字節就是用來放TCP傳來的TCP報文段或者UDP傳來的UDP數據報的(
如果讀者對UDP包不清楚可以查看本人前幾天的關於UDP的解析)。又因為UDP數據報的首部8字節,所以UDP數據報的數據區最大長度為1472字節。這個1472字節就是我們可以使用的字節數。怎麼樣?看了這樣的分析之後是不是清晰了很多。
這個時候讀者可能會有一個疑問,我自己也有一個疑問。
當我們發送的UDP數據大於1472的時候會怎樣呢? 這也就是說IP數據報大於1500字節,大於MTU,這個時候發送方IP層就需要分片(fragmentation)。把數據報分成若干片,使每一片都小於MTU,而接收方IP層則需要進行數據報的重組。這樣就會多做許多事情,而更嚴重的是,由於UDP的特性,當某一片數據傳送中丟失時,接收方無法重組數據報,將導致丟棄整個UDP數據報。
因此,在一般的局域網環境下,我建議將UDP的數據長度控制在1472字節以下為最佳
結論2:Internet編程時,建議將UDP數據控制在548字節以下
進行Internet編程時則不同,因為Internet上的路由器可能會將MTU設為不同的值。如果我們假定MTU為1500來發送數據,而途經的某個網絡的MTU值小於1500字節,那麼系統將會使用一系列的機制來調整MTU值,使數據報能夠順利到達目的地,這樣就會做許多不必要的操作。
鑑於Internet上的標準MTU值為576字節,所以我建議在進行Internet的UDP編程時, 最好將UDP的數據長度控件在548字節(576-8-20)以內。
感覺我上面的話貌似有問題,unix網絡編程第一卷裡說:ipv4協議規定ip層的最小重組緩衝區大小為576!所以,建議udp包不要超過這個大小,而不是因為internet的標準MTU是576!
告訴我,你們的理解吧!
喜歡我的文章的話,就關注我吧!不要只收藏和轉發哦,每天至少兩篇編程知識給大家,都是本人多年的經驗總結!
閱讀更多 cpp軟件架構獅 的文章