網絡編程的一些坑

Tcp Udp發送包的大小限制問題

以太網(Ethernet)數據幀的長度必須在46-1500字節之間,這是由以太網的物理特性決定的.  
  這個1500字節被稱爲鏈路層的MTU(最大傳輸單元).  
  但這並不是指鏈路層的長度被限制在1500字節,其實這這個MTU指的是鏈路層的數據區.  
  並不包括鏈路層的首部和尾部的18個字節.

因爲IP數據報的首部爲20字節,所以IP數據報的數據區長度最大爲1480字節. 

又因爲UDP數據報的首部8字節,所以UDP數據報的數據區最大長度爲1472字節. 

鑑於Internet上的標準MTU值爲576字節,所以我建議在進行Internet的UDP編程時. 

 

 

tcp每次發送的包大小  最大爲65535個字節,

udp給本機發送數據,單包的大小最大爲4000個字節,

udp給其他主機發送數據,單包的大小最大爲1500字節,

超過udp可能丟包,或者發不出去

#define MAX_TCP_SIZE 65536
#define IP_MTU_SIZE 1500
#define MAX_UDP_SIZE 4096
#define MIN_UDP_SIZE 576

UDP包最小長度限制的問題

以前知道UDP包最大不能超過65535個字節,這是因爲UDP包頭中的長度用了兩個字節來表示。但最近發現,過小的UDP包也發不出去。

最近在公司寫了個基於UDP協議的日誌收集服務,邏輯很簡單,客戶端(PHP應用)通過socket把數據發過來,服務端記錄日誌並返回成功。由於開發測試時Server和Client都是同一臺機器上,一直平安無事。後來又找了臺機器想做一下壓力,卻發現無論如何Client都不到回包。通過tcpdump看,Server端的確已經回包了,但Client機器上只能看到一個發包。

這個問題排查了整個下午,因爲一直沒有頭緒。最初想到的是網絡原因,可能端口被防火牆攔截,但用nc試驗收發包,沒有問題,所以排除了網絡原因。然後懷疑是不是某些系統調用出問題了?寫了一段最簡單的udp收發包代碼,發現也沒有問題。然後懷疑是不是框架出問題了,打了一些點,重新編譯,也沒有發現異常,這時想到之前用同一個框架寫的服務,找出來編譯運行,發現竟然可以正常收發包。然後我開始修改這個服務的發包部分,逐漸減少sendto的內容,直到不行,這時開始懷疑是不是UDP包有最小長度限制。

Google了一下,果然有人遇到類似問題。
http://bbs.csdn.net/topics/390729121
http://bbs.csdn.net/topics/60272470

繼續查,發現802.3規定,以太網幀的數據部分是46~1500字節,如下圖。而IP包頭部佔了20個字節,UDP包頭部佔了8個字節,還有18個字節需要填滿。但測試發現,當數據部分(不含IP包頭與UDP包頭)小於12個字節時,會發送失敗;當數據庫部分大於等於12個字節而小於18個字節時,會自動被0補齊18個字節,併發送成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章