1. 程式人生 > >網路傳輸一丟丟記錄【資料包大小限制】

網路傳輸一丟丟記錄【資料包大小限制】

今早用udp傳一個物件序列化位元組陣列,大小達到了7000+位元組,然後udp的send就報異常;

“一個在資料報套接字上傳送的訊息大於內部訊息緩衝區或其他一些網路限制,或該使用者用於接收資料報的緩衝區比資料報小。”

網上查了一下,說是超過udp的單包容量(一般不超過1000位元組),所以報錯。如果用udp傳大的資料包(比如傳一個檔案)標準做法是分包傳送,比如,先把檔案分包,256一個包,每包資料的第一個位元組,放包序號,這樣收到後,再組裝。傳小資料,則不用分包。

相關有用參考

UDP不會自動拆包,必須在傳送前自行將資料拆分後傳送,超過1500的必須拆分,安全起見設定為1400。
另外為了UDP傳輸的安全性,每個資料包的前面第一個位元組必須用來存放當前包序號,為了序號不連續的丟包現象能及時被發現並重傳,而整個資料的大小應該在序號為0的資料包後僅跟著4位元組長度(int型別)來指明。

如果你傳超過乙太網幀(1500位元組左右)的資料,udp就不太適合,否則udp可能亂序,你自己維護序列號得煩死你

可是為什麼99%的情況下傳幾十k的資料都沒問題呢?我……

如果我沒記錯,TCP/IP詳解裡說了udp是可以自動分片的,因為udp是傳輸層,而分片是更底層的ip層做的,不是一個層級

你的問題可能就是傳輸中丟包或亂序了

徹底解決udp的丟包和亂序,需要有個流水號記錄順序和丟失狀況,還有有超時重發機制,這個超時重發通常又是重發全部而不是一個包,因為你不知道哪個包丟了,讓對端告訴你的話這個“通知”一樣可能丟

如果udp沒開校驗和,還需要加個crc之類的保證沒有電磁干擾造成的錯誤

最後就相當於自己實現tcp,開銷往往比直接用tcp還大

所以udp只適合不怕丟包,不怕亂序的場合

udp有限制

常見IP碎片攻擊詳解
http://fanqiang.chinaunix.net/a5/b2/20021205/060200350.html
1. 為什麼存在IP碎片 
-=-=-=-=-=-=-=-=-=-=-= 
鏈路層具有最大傳輸單元MTU這個特性,它限制了資料幀的最大長度,不同的網路型別都有一 
個上限值。乙太網的MTU是1500,你可以用 netstat -i 命令檢視這個值。如果IP層有資料包 
要傳,而且資料包的長度超過了MTU,那麼IP層就要對資料包進行分片(fragmentation)操 
作,使每一片的長度都小於或等於MTU。我們假設要傳輸一個UDP資料包,乙太網的MTU為150 

位元組,一般IP首部為20位元組,UDP首部為8位元組,資料的淨荷(payload)部分預留是 
1500-20-8=1472位元組。如果資料部分大於1472位元組,就會出現分片現象。 

(1)控制包的大小 IP層最大65535位元組(ip包頭長度16bit)決定UDP最大為65535-20-8(28為Ip包頭與udp包頭大小之和),鏈路層MTU(不同介質MTU大小不同,最小的296),當IP包大於MTU會造成IP層分片,容易導致丟片,所以為了避免分片常用包的大小為256,有的為512。
(2)把檔案流按統一長度,分包傳送。每個包至少兩部分組成:順序號+檔案位元組資料。
(3)接收時,安照順序號,把收到的資料組裝成一個檔案。
(4)第一個包 包括:總檔案長度,資料包數;最後一個包 加上結束標誌
(5)還可以加校驗位,資料包中的規則自己可以發揮,根據需要自己規定就行了。

以下兩篇講的很好