1. 程式人生 > >unix udp sendto 最大可傳送的資料長度

unix udp sendto 最大可傳送的資料長度

sendto 的最大可傳送資料長度受限於兩個值。

第一 【2^16 -1 - 8 -20】 

第二 【SO_SNDBUF】

解釋受限於【2^16-1-8-20】

資料封裝過程

第一步: 使用者層 : user資料

第二步: udp層資料: udp首部(8) + user資料

第三步: 

              ip層資料報文: ip首部(20) + udp首部(8) + user 資料

              因為,ip首部中用於表示ip資料報文段的長度為16bit,所有ip最大可封裝的資料長度為【2^16-1-20】

              所以user資料的最大長度為【2^16-1-20-8】.

              注意引起ip分片是因為ip資料報文段>MTU(受限於鏈路層最大傳輸長度)。

              而不是上層資料[udp首部+user資料]>[2^16-1-20],如果上層資料大於[2^16-1-20],將向上層返回錯誤。

              ip層的處理情況可以這樣理解: 

              1 將上層資料封裝成一個ip資料報文,如果資料報文的資料部分大於【2^16-1-20】,返回錯誤

              2 如果ip資料報文段大於MTU,則將該ip資料報文段進行分片處理,分成多個ip資料報文段

所以, 當sendto資料超過【2^16-1-20-8】時,系統會返回 Message too long

錯誤。

受限於【SO_SNDBUF】情況

SO_SNDBUF 可由getsockopt 檢視,可由setsockopt 設定

SO_SNDBUF 規定了ip層用於傳送udp資料最大可分配空間的長度為Max_mem_alloc,一般Max_mem_alloc>=SO_SNDBUF

簡而言之,ip層分配用於傳送的報文段時,會檢視已分配size_alloc的大小是否大於SO_SNDBUF

                 如果size_alloc大於等於SO_SNDBUF,則分配失敗,即該udp資料報文傳送失敗No buffer space available

                 如果size_alloc小於SO_SNDBUF, 則分配成功成功

                 所以,有可能最後一次分配完時,已分配的size_alloc 會大於SO_SNDBUF

關鍵在於理解,每次分配是否成功取決於是否還有剩下的,而不在與剩下的夠不夠分配,