讨论:互联网上能通过的Udp包的字节数,通常是多少?(300分)

  • 主题发起人 主题发起人
  • 开始时间 开始时间

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,一个Udp数据包,我不去拆分它.直接就SendBuffer它.那在互联网内网的环境下,好多网关会过滤掉过于庞大的数据包.问题就是,这个数据包最大能够有多大,能够正常在互联网上传输.这里不讨论人为拆分成数据足够小的包.
 
[:D][:D][:D][:D][:D][:D]快说.
 
1K 是安全.大于1K的UDP包有可能被网关拦.
 
你可以测试一下了,..自己试验不就完了,,,,我估计100K,....
 
UDP優點
易消化無負擔,簡易輕便好攜帶
UDP缺點
上不了抬面、不可靠
資料容易被搞丟

UDP数据包问题:
1.不能保证每个包的先后顺序(因为无连接的,每次传输的路线可能不尽相同),
只有在接收中分析包的顺序, 但可以保证以MTU(最大传输单位[以太网1500左右])
为基准的包传输,不存在边界问题,可完整读取,以便于分析这个包。
如果丢包就是整包,不会将包丢一部分,留一部分。
2.UDP可能有时会丢包,那么本次会话的数据包就不是正确的,在处理超时时,
发现本次会话的数据包超时没有接收完成,就删除该会话数据包。
3.同样将包缓存,再在缓存中分析包,计算CRC, 并取出来处理。

设计UDP数据包: 以下可以理解为一个结构,当然其中还要加其规则可以更改。

数据流的类型: 1字节(Byte); MSG_DATA or MSG_ENCODE or MSG_TEXT
数据校验码: 2字节(WORD); CRC校验
流水号: 4字节(Int);
总包数: 2字节(WORD) ; 本次会话总包数
当前包ID: 2字节(WORD); 本次传输的包数
数据段: N字节,根据实际情况来定。
前11字节为包头,后面的字节为真实数据;
下面更容易理解:
1. 顺序组包发送.
a. 1节,包头数据类型标识(加密,文本,数据流);
b. 8节,包的流水号(以防重发);
c. 1节,写入0表示完整一包,其它表示不完整,并代表后面的多少份之几(n/x) 之类的
长度;如果完整直接进行d,写入数据长度,否则写入组头长度Length(n/x),组头内
容(n/x)。
d. 4节,写入真正的数据的长度。
2. 顺序拆包分析
a. 1节,读取包头数据类型标识(加密,文本,数据流);
b. 8节,读取包的流水号(比较以防重发);
c. 1节,0表示完整一包,其它表示不完整,并代表后面的多少份之几(n/x) 之类的长度;
如果完整直接进行d,读取数据长度,否则读取组头长度Length(n/x),组头内容(n/x)。
d. 4节,真正的数据的长度
 
UDP报文本身也是可能被拆分的.(可能拆分成多个IP包),因此我想你所指的应该是不允许IP包拆分的UDP报文。在802.3网络最大的数据帧是1536,当然里边包含了很多协议头,数据大概在1500左右.协议中有MTU/MRU等参数。这个参数通常会自我调整,(通过ICMP错误控制),因为它应该是网络上所有路由器网络的最小值,通常情况下,1K多一点是没问题的,超过1.5K基本上是有问题的.
 
那么indy的buffersize的默认值为8192是否一次可以发8K.
 
我测试,在互联网上常常不行.[:(!]
 
Udp包如果收到了,那还不够保证它的信息是完整的吗?
 
1024 2048 4096 大于4096的UDP数据包非常容易掉
在互网上跑我一般选1024。
 
Anylib 组件,自由界面和报表的完美组合!
http://www.anylib.com
 
像DNS报文,如果数据大于512字节,那么就必须使用TCP查询
具体你是可以自己尝试的.
1.你可以在开发之前试验,1.5K指的是在802.3的局域网.而在互联网上,小于512可以保证没问题,因为这是DNS协议其中的一部分,在此之间,可能就和网络环境有关了.比如通过ADSL/GPRS/MODEM很有可能这些参数就不一样.因为结果数值应该是各个环节(网关/路由器)的最小值. UDP协议中可以指定该报文不能被拆分成多个IP帧传送。(我不能确定是在UDP报头中,很可能在IP报头中,请自己参考UDP协议)
2.你可以在程序的运行时通过上边的方法检测,从而动态调整.
另外,如果你是数据产生/消费模式,那么其实通过允许IP拆包,可能并不会怎么影响数据传输速率,毕竟丢帧情况是很少见的.特别是那些对数据丢失不敏感的程序,比如屏幕监控.不过这样可能会影响双方交互的速度.因为协议层只会提交完整的UDP报文,而不是像TCP,只要顺序对,直接就提交应用了.
 
我的意思不是:不会被拆分更小包的UDP最大字符数是多少.
而是:不管会不会拆包,在发送方发送,能正确到达接收方的UDP包的最大字节数是多少.

zjan521的回答很精辟.
 
理论上是不超过1.5k都可以
 
8192,在CDMA、GPRS、固网都试过,没有发现什么问题,但是数据量大的时候,大概1M以上,有比较频繁的丢包现象
 
UDP本身就是不可靠连接,因此丢IP包在所难免.而只要一个IP包丢失,整个UDP报文就是无效的,也就不会被上交到应用程序.因此我想你的问题似乎是走偏了.
不考虑网络数据丢失本身.UDP报文包头中的数据长度是16位的,因此包括包头最大只能是65536字节,也就是64K.而大于1.5k(约,802.3),那么这个UDP报文肯定被分成多个IP包,如果被允许的话.而定义一个IP包在整个报文中的位置好像使用了一个8比特的字节数据,如果我没记错的话,这就意味着最多只能拆分成256(?)个左右的IP包,按照802.3的1.5k一个IP包来计算,大于64K,因此一个UDP报文从协议角度上讲,最多可以传输约64K的数据.
但是这似乎没有什么意义.因为首先UDP是不可靠传输,可能会丢失一些IP包,从而导致整个UDP包传输失败,在网络较差的时候,如此大的报文很可能导致网络问题(假设每隔42个IP包丢失一个,而你使用了64K的报文,被拆分成42个左右的IP包传输,这就意味着没有任何成功传输的数据.).其次,一个应用程序可以发送的数据是无限制的,对于应用程序而言,对于大数据的应用程序,通常会在数据内部实现通信传输,完整UDP报文的概念对于程序上层逻辑并不是不可或缺的,报文的概念仅仅存在于直接进行网络通信的地方,而通过简单的封装,程序上层逻辑完全可以不接触这些(上层应用程序可以看作提交的是逻辑报文而不是网络UDP报文).

综合上述,我想[ 而是:不管会不会拆包 ]这个恰恰是你思维走偏的地方,你的问题本身就不完善.而且这个问题本身可能就欠缺实际意义.因为在不同的网络情况下,答案很可能是不同的.比如在某一级路由器上有可能不允许UDP报文分拆.如果你真的需要答案,那么动态监测应该是比较合适的.因为最大不超过64K,最小也要是512字节.通过二分法,若干个报文,百余K的流量,即可检测出大致结果.在出现通信问题的时候,即时检测.SO IT IS ENDING!
 
后退
顶部