
程序同时发送到本地应用和远程应用的,虽然是不同的IP和端口,但是是同一个逻辑,所以程序的本身的问题可能性比较小,先测试下是否为网络问题:
首先,我们来看下这个1472是怎么来的,在以太网环境中,以太网的帧的body大小为46字节到1500字节之间,本次是处于IPV4的环境,IP包头大小为20个字节,所以还剩下1480字节UDP的协议的报文头长度为8个字节,所以剩下的udp的包体长度为1480-8 = 1472个字节,具体展示如下图:
格式如下:
上述告警意思是因为我们环境下网卡的MTU设置为1500个字节,如下:
因为发送的UDP报文长度大于可以传输的安全长度1472个字节,这不代表不能发送,只是因为大于了帧的最大传输长度,所以在IP层需要进行分包,一旦网络环境不好,分包产生了丢失问题,会造成IP的组包失败,从而导致UDP的报文丢失.
还可以通过 netstat -su 进行监控:
既然MTU太小了,那么尝试修改下两端的MTU最大值,MTU是取整个路由的MTU最小值,我们尝试把两端的MTU增大下:
两端MTU增加后,仍然会报错,那么可能的原因是中间路由设备设置的MTU比较小,查看下,由于主机上没有traceroute命令来跟踪,尝试使用另外一个命令:
类似于traceroute,可以追踪路由,结束后打印MTU值.
还可以带个端口,测试这个UDP端口.
在实际环境中,由于中间很多路由都看不到,而且让中间的所有路由都改MTU值不是太现实.
在MTU为1500字节的情况下,如果发送的UDP报文大于MTU,比如发送8000个字节,如果包缓存足够,且分包按照正确的顺序到来,通过recvfrom(9000) 还是可以收到一个完整的UDP包的. 如果IP分片丢失,校验失败,包就会丢弃.recvfrom(9000)将阻塞.
为防止socket缓冲区溢出造成的问题,特意增加了socket的缓冲区.
cat /proc/sys/net/core/rmem_default 和 cat /proc/sys/net/core/rmem_max 可以查看socket缓冲区的缺省值和最大值。
可以通过 echo xxx >/proc/sys/net/core/rmem_default 的方法来临时修改,也通过更改/etc/sysctl.conf文件添加以下配置来修改:
修改完成后记得运行以下命令来生效:
但是在本次仍然没起到效果.
最终解决方法是绕过了这个问题,直接改了接口,不采用UDP发送了,而是采用文件采集形式.
这是一次不成功的经验,有这方面经验的朋友,可以留言交流下还有什么原因造成这种问题.
前言
当我们做安卓开发时,大多数人还是习惯用虚拟机,毕竟真机巴拉来巴拉去的不如鼠标方便,尤其是调试一些功能模块时,比如socket udp , 下文说明如何用as+虚拟机调试 socket udp, 实测
如何搭建udp服务器和客户端不提了,简单的搭建随便找一个吧
首先我们的前提是 我们在pc上建立了一个UDP服务器,目的是通过这服务器给虚拟机发送一个udp包
但如何发送这个包呢?
如果想当然的这样做在server上给"127.0.0.1:9014"发送包,然后在虚拟机的9014端口接受包,你会发现无论发多少次,虚拟机什么都收不到。 原因是,你这个包并不是发给虚拟机了,而是发给了本地端口,
也许你会说,给虚拟机发应该用虚拟机的ip地址,好的,通过尝试我们发现给虚拟机的ip地址+9014端口,仍然无法收到。(我用工具查看的虚拟机ip地址是10.0.2.15)
正确步骤
1.把PC端口9014映射到虚拟机,意思就是当PC 9014端口收到udp包,它会转发给虚拟机相应的端口
使用windows程序telnet即可达到映射的目的,(注意Telnet在win10需要开启,可查找怎么开启这个程序)
打开cmd 输入如下命令连接到本地虚拟机
telnet localhost 5554
连接成功后他会提示你输入验证,并告诉你验证码在哪里
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)