关于netty UDP不能发送大于2048字节包的问题
2017-06-05 10:10
901 查看
刚开始对netty udp不太熟的朋友可能会遇到这么一个问题,在使用netty udp发送数据的时候,如果你的包比较大,或者超过2048字节的时候,经常会接收不全或者丢包了。比如发送一个4096字节的DatagramPacket包到服务器,你会发现只接收到2048或者更少的字节。是什么原因呢?下面说一下个人的见解:
udp理论上支持最大发送64K的包,那为什么netty udp不能发送大于2048字节呢?实际上网络通信中,还受到很多其他因素的影响,netty udp并非不能发送大于2048字节的包。而是收到MTU的影响。MTU【最大传输单元(Maximum
Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络接口卡、串口等)】。
MTU国际默认规定是1500,不同的网络接入方式,不同地区的网络运营商,甚至不同的路由器,它们的MTU值都可能是不同的,例如:ADSL接入时MTU为1492字节。操作系统中可以通过命令查看:netsh
interface ipv4 show subinterfaces
如上图,第一列可以看到MTU值为1500(win10系统)。一般默认第一个就是正在使用的网卡,我这边安装有虚拟机,所以可以看到几个虚拟网卡。
netty udp每次发送的包要经过网卡接收到能传到应用程序。如图MTU就像一扇门。每次只允许1500个字节通过,所以当你发送大于1500个字节的数据包时。就会被分开多次传输,每次只传输1500个字节。所以为什么你用netty udp发送比较大的包时会接收不完全,因为你的数据被自动分割成了几个包了。总之在我们常用的以太网中,MTU是1500字节。超过此大小的数据包就会将多余的部分拆分再单独传输。就像货车通过限高的桥洞一样,货物高度超过限制高度了,就需要卸下一些货物,分两批通过限高路段。
有些朋友可能发现了问题,既然最大只能发送1500个字节,那为什么我的可以接收2048个字节呢?这就跟内存页有点关系了,为了4K对齐,内存包缓存是2048。所以实际上你每次接收依然最大是1500,只是内存为你做了一下缓存了而已,什么是4K对齐这里就不介绍了,可以上网查一下。
MTU的值是可以修改的,不一定就是1500。可以通过命令 :netsh interface ipv4 set subinterface "本地连接" mtu=1480 store=persistent”命令,然后回车,就可以对本地连接MTU值进行修改;再次输入“netsh
interface ipv4 show subinterfaces ”命令,即可查询到目前系统的MTU值,这时候会发现MTU值已经修改成1480了;但不推荐修改这个值。因为系统与ISP之间MTU的不符就会直接导致数据在网络传输过程中不断地进行分包、组包,浪费了宝贵的传输时间,也严重影响了宽带的工作效率。
最后说一下netty udp每次发送包大小的建议,因为国内很多用户的上网方式都是ADSL。而ADSL的MTU值1492。但每个UDP包都包含28字节的“数据包报头”,所以实际你每次只能发送的数据是1464个字节。
当然,怎么用还是要根据具体的需求而定。
udp理论上支持最大发送64K的包,那为什么netty udp不能发送大于2048字节呢?实际上网络通信中,还受到很多其他因素的影响,netty udp并非不能发送大于2048字节的包。而是收到MTU的影响。MTU【最大传输单元(Maximum
Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络接口卡、串口等)】。
MTU国际默认规定是1500,不同的网络接入方式,不同地区的网络运营商,甚至不同的路由器,它们的MTU值都可能是不同的,例如:ADSL接入时MTU为1492字节。操作系统中可以通过命令查看:netsh
interface ipv4 show subinterfaces
如上图,第一列可以看到MTU值为1500(win10系统)。一般默认第一个就是正在使用的网卡,我这边安装有虚拟机,所以可以看到几个虚拟网卡。
netty udp每次发送的包要经过网卡接收到能传到应用程序。如图MTU就像一扇门。每次只允许1500个字节通过,所以当你发送大于1500个字节的数据包时。就会被分开多次传输,每次只传输1500个字节。所以为什么你用netty udp发送比较大的包时会接收不完全,因为你的数据被自动分割成了几个包了。总之在我们常用的以太网中,MTU是1500字节。超过此大小的数据包就会将多余的部分拆分再单独传输。就像货车通过限高的桥洞一样,货物高度超过限制高度了,就需要卸下一些货物,分两批通过限高路段。
有些朋友可能发现了问题,既然最大只能发送1500个字节,那为什么我的可以接收2048个字节呢?这就跟内存页有点关系了,为了4K对齐,内存包缓存是2048。所以实际上你每次接收依然最大是1500,只是内存为你做了一下缓存了而已,什么是4K对齐这里就不介绍了,可以上网查一下。
MTU的值是可以修改的,不一定就是1500。可以通过命令 :netsh interface ipv4 set subinterface "本地连接" mtu=1480 store=persistent”命令,然后回车,就可以对本地连接MTU值进行修改;再次输入“netsh
interface ipv4 show subinterfaces ”命令,即可查询到目前系统的MTU值,这时候会发现MTU值已经修改成1480了;但不推荐修改这个值。因为系统与ISP之间MTU的不符就会直接导致数据在网络传输过程中不断地进行分包、组包,浪费了宝贵的传输时间,也严重影响了宽带的工作效率。
最后说一下netty udp每次发送包大小的建议,因为国内很多用户的上网方式都是ADSL。而ADSL的MTU值1492。但每个UDP包都包含28字节的“数据包报头”,所以实际你每次只能发送的数据是1464个字节。
当然,怎么用还是要根据具体的需求而定。
相关文章推荐
- 为什么udp为什么不能发送大于1472字节数据
- 为什么udp为什么不能发送大于1472字节数据
- 为什么udp为什么不能发送大于1472字节数据
- (原)关于udp的socket发送数据耗时的问题探讨
- 再论Tcp Udp 发送、接收 0字节问题
- 关于RS485通讯中使用STM32串口以DMA方式发送数据丢失字节的问题
- 关于使用VBS脚本不能发送密码的问题
- LWIP UDP socket编程 可以指定本地端口号及发送长度不能太长问题分析
- TCP、UDP 发送、接收0字节问题
- 关于android&java在socket通讯单字节大于127的问题
- 再论Tcp Udp 发送、接收 0字节问题
- 关于java用udp发送文件的问题...
- python的UDP中,server自己给自己发信息,不能发送到client的问题
- LWIP UDP socket编程 可以指定本地端口号及发送长度不能太长问题分析
- 关于linux下的udp/tcp通信设置发送sendto/接收recvfrom信息超时的参数。解决通道堵塞问题。
- 关于outlook不能发送126邮件的问题
- 关于Jmail不能发送邮件问题
- 关于saba不能发送中文邮件问题解决
- 关于Rs485通信只能接收不能发送的问题
- 关于单片机TCP/IP协议栈的实现目前的进度和问题——TCP或UDP发送数据,端口绑定问题