大白话:局域网 mtu 1500;Internet mtu 576
对于UDP协议来说,整个包的最大长度为65535,其中包头长度是20字节(包括了伪首部:这个伪首部其实是属于ip头部的部分,里面有源ip地址和目标ip地址)所以UDP实际可用携带的最大数据是:65515字节长度。【udp协议里面:长度占了2个字节,16位。能够表示的范围是2^16-1 即 0-65515】
去除20字节的IP首部和8个字节的UDP首部,UDP数据报中用户数据的最长长度为65507字节。但是,大多数实现所提供的长度比这个最大值小。
我们将遇到两个限制因素。第一,应用程序可能会受到其程序接口的限制。socket API提供了一个可供应用程序调用的函数,以设置接收和发送缓存的长度。对于UDP socket,这个长度与应用程序可以读写的最大UDP数据报的长度直接相关。现在的大部分系统都默认提供了可读写大于8192字节的UDP数据报(使用这个默认值是因为8192是NFS读写用户数据数的默认值)。
第二个限制来自于TCP/IP的内核实现。可能存在一些实现特性(或差错),使IP数据报长度小于65535字节。
在SunOS 4.1.3下使用环回接口的最大IP数据报长度是32767字节。比它大的值都会发生差错。
但是从BSD/386到SunOS 4.1.3的情况下,Sun所能接收到最大IP数据报长度为32786字节(即32758字节用户数据)。
在Solaris 2.2下使用环回接口,最大可收发IP数据报长度为65535字节。
从Solaris 2.2到AIX 3.2.2,发送的最大IP数据报长度可以是65535字节。很显然,这个限制与源端和目的端的实现有关。
主机必须能够接收最短为576字节的IP数据报。在许多UDP应用程序的设计中,其应用程序数据被限制成512字节或更小,因此比这个限制值小。
由于IP能够发送或接收特定长度的数据报并不意味着接收应用程序可以读取该长度的数据。因此,UDP编程接口允许应用程序指定每次返回的最大字节数。如果接收到的数据报长度大于应用程序所能处理的长度,那么会发生什么情况呢?不幸的是,该问题的答案取决于编程接口和实现。
典型的Berkeley版socket API对数据报进行截断,并丢弃任何多余的数据。应用程序何时能够知道,则与版本有关(4.3BSD Reno及其后的版本可以通知应用程序数据报被截断)。
SVR4 下的socket API(包括Solaris 2.x) 并不截断数据报。超出部分数据在后面的读取中返回。它也不通知应用程序从单个UDP数据报中多次进行读取操作。TLI API不丢弃数据。相反,它返回一个标志表明可以获得更多的数据,而应用程序后面的读操作将返回数据报的其余部分。在讨论TCP时,我们发现它为应用程序提供连续的字节流,而没有任何信息边界。TCP以应用程序读操作时所要求的长度来传送数据,因此,在这个接口下,不会发生数据丢失。
对于TCP协议来说,整个包的最大长度是由最大传输大小(MSS,Maxitum Segment Size)决定,MSS就是TCP数据包每次能够传 输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值 ,确定为这次连接的最大MSS值。
IP层:
对于IP协议来说,IP包的大小由MTU决定(IP数据包长度就是MTU-28(包头长度)。 MTU值越大,封包就越大,理论上可增加传送速率,但 MTU值又不能设得太大,因为封包太大,传送时出现错误的机会大增。
UDP 包的大小就应该是 1500 – IP头(20) – UDP头(8) = 1472(BYTES)
TCP 包的大小就应该是 1500 – IP头(20) – TCP头(20) = 1460 (BYTES)
当我们发送的UDP数据大于1472的时候会怎样呢?这也就是说IP数据报大于1500字节,大于 MTU.这个时候发送方IP层就需要分片(fragmentation).把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组.这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便无法重组数据报.将导致丢弃整个UDP数据报。
因此,在普通的局域网环境下,我建议将UDP的数据控制在1472字节以下为好.
进行Internet编程时则不同,因为Internet上的路由器可能会将MTU设为不同的值.如果我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机制来调整MTU值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作.
一般默认的设置,PPPoE连接的最高MTU值是1492, 而以太网 (Ethernet)的最高MTU值则是1500,而在Internet上,默认的MTU大小是576字节。
鉴于 Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时.最好将UDP的数据长度控件在548字节 (576-8-20)以内.
许多服务器将最大的UDP数据包限制为512字节(如dns)
IPv4 最小重组缓冲区大小是576,IPv6在1500处。从这里减去标头大小。请参阅W. Richard Stevens的UNIX网络编程
576字节是最小的缓冲区大小,即每个实现必须能够重组至少那个大小的分组。有关详细信息,请参阅IETF RFC 1122。
安全UDP的有效载荷最大是508字节。这是一个数据包大小为576,减去最多60个字节的IP标头和8个字节的UDP标头。任何这个规模或更小的UDP有效载荷都保证可以通过IP交付(尽管不能保证完整的交付)。由于其他原因,在路由的过程中可能会丢失。除了仅IPv6路由,最大有效载荷为1,212字节。正如其他人所提到的,在某些情况下可以添加额外的协议头。取而代之的是300-400字节的存储空间。
任何UDP数据包都可能被分割。这并不重要,因为丢失一个数据包与丢失一个未分组的数据包具有相同的效果:使用UDP,整个分组被丢弃的这种种情况是可能发生的。
一个典型 IPv4报头为20个字节,和UDP头部为8个字节。但是又包含IP选项,这可以将IP报头的大小增加到60个字节。另外,有时中间节点需要将数据报封装在另一个协议中,如IPsec(用于VPN等),以便将数据包路由到目的地。因此,如果你不知道MTU特定网络路径的话,最好为其他标题信息留下合理的存储空间,可能这些信息并不是你预期的。通常认为UDP的有效载荷是512字节,即使这样处理也不能为最大尺寸的IP标头留下足够的存储空间。
抓包实测 – UDP/TCP数据包分析
经测试,局域网环境下,UDP包大小为1024*8,速度达到2M/s,丢包情况理想.
外网环境下,UDP包大小为548,速度理想,丢包情况理想.
本文旨在分析使用抓包工具抓取到的数据包。
(一)抓包工具
tcpdump:linux下的抓包利器
wireshark:带GUI的抓包工具,其前身是大名鼎鼎的Ethereal
(二)抓包
这里只简述tcpdump的一般用法,详细资料可参考tcpdump使用手册。
wireshark带有GUI,操作比较简单,暂不赘述。
tcpdump -i eth1 tcp -Xnlps0 port 16815 src host 192.168.0.0 and dst net 192.168.0.1
tcpdump -i eth1 -Xnlps0 dst net 172.23.9.155 and port 37861
tcpdump -i eth1 -Xnlps0 dst net 172.23.9.155 and port 37861 -w yourfile
PS:可以使用wireshark分析tcpdump抓取的数据包
tcpdump -w output.cap -s0
wireshark可以在图形界面下分析应用层按照TCP/IP四层结构显显示数据包,
第一行是数据链路层的信息,
第二行是网络层信息(IP协议),
第三行是传输层信息(TCP协议),
第四行是应用层信息(HTTP协议),
可以展开每一行用来观察具体的内容
(三)TCP/UDP数据包结构
抓包分析,装载udp的ip包和装载tcp的ip包,查明ip包首部都没有添加可选项。
PS:后面的数据分析都是带IP头的数据包。
(四)UDP数据包分析
0x0000: 4500 0054 9a08 4000 4011 b88d ac17 8639 E..T..@.@……9
0x0010: ac17 099b e317 93e5 0040 e854 0000 0065 ………@.T…e
0x0020: 012d d668 0000 0000 0000 0000 0000 0038 .-.h………..8
0x0030: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
0x0040: 0000 0001 0000 0000 0000 0000 0000 0000 …………….
0x0050: 0000 0000
4500 [4: ipv4], [5: header length, *4 ==> 20], [00: Type of Service(TOS)]
0054 [total length: 0x54(84), ip header(20) + udp header(8) + packlen(56) -> 84]
9a08 id
4000 3bits(ip flags), 40 -> do not flag, 5bits: fragment offset
4011 [ttl: 40], [protocol: 0x11(17) ==> udp]
b88d checksum
ac17 8639 source ip: 172.23.134.57
ac17 099b dest ip: 172.23.9.155
e317 sourc port: 58135 (ntohs(0xe317)) [exchange]
93e5 dest port: 37861
0040 length: 64
e854 checksum
0000 0065… data
(五)TCP数据包分析
0x0000: 4500 0073 cdc5 4000 4006 6285 ca6e 4099 E..s..@[email protected]@.
0x0010: 7474 8abe 1f40 070a 6d88 acdd 23d7 a448 tt…@..m…#..H
0x0020: 5018 16d0 0aa0 0000 0100 8000 0000 0047 P…………..G
0x0030: 3004 8000 0016 8117 04d7 cd00 000b 0006 0……………
0x0040: 4500 1a4d 6bd0 180a 909a bc08 883d edea E..Mk……..=..
0x0050: 091f ..
4500 [4: ipv4] [5: ip header length, 4*5 -> 20] [00 TOS]
0073 [total length: 0x73(115), ip header(20) + tcp header(20) + packlen(75) -> 115]
cdc5 id(ignore it)
4000 3bits(ip flags), 40 -> do not flag, 5bits: fragment offset
4006 [40 ttl] [06 protocol, 0x06 -> tcp]
6285 checksum
ca6e 4099 source ip: 202.110.64.153
7474 8abe dest ip: 116.116.138.190
1f40 sourc port: 8000 (ntohs(0x401f)) [exchange]
070a dest port: 1802
6d88 acdd 32 bits sequence number(ignore)
23d7 a448 32 bits ack(ignore)
5018 [5: tcp header length 5 * 4 -> 20] [018: 0000 00/01 1000: reserved 6bit -> ACK+PUSH] (URG|ACK|PSH|RST|SYN|FIN)
16d0 16bit window size: 5840
0aa0 16bit tcp checksum(ignore)
0000 16bit urgent pointer
———————
抓包工具:科来网络分析系统
https://blog.csdn.net/cybertan/article/details/5961049
参考:
https://blog.csdn.net/wirror800/article/details/6977421
https://blog.csdn.net/buptzwp/article/details/5055487