-
问题
我们的项目中需要适配一个雷达设备,雷达上报数据方式是通过多播(组播)的方式。加入这个组里面就能得到雷达上报的数据,简单来说就是雷达上报之后,在这个组里的ip都可以获得者段数据。
然后我在本地调试好代码之后想着大功告成直接上传软件,重启一下服务,这部分就完成啦。但是服务重启后,接收不到数据。大概就是这样子。
解决过程
- 首先确定数据包是从哪里被丢弃,也就是被过滤掉的。先解释一下我们测试环境的网络架构。是简易型的哈
- 因为我的电脑本身可以接收到数据,所以这就证明路由器和交换机没有丢弃UDP数据包,在网络架构上来说测试服务器和我的电脑一样都是一个服务器,拥有一个ip,但是接收不到,就很奇怪。因为测试服务器是一个宿主机上的虚拟机,所以我就以为是vmware workstation pro做了一些限制。
- 我就去官网搜,发现并没有这部分限制,我就去外网搜,发现也没有,所以我就觉得这块可能真的没有问题。
- 虚拟机是配置了两个虚拟网卡,网上说必须设置成桥接模式,我的网卡ens33是桥接,ens37是NAT模式,但是我是想从ens33中获取数据,所以我不是网卡模式的问题。
- 然后我就尝试手动添加udp组播地址,发现加不上,添加这个就会自动被添加到ens37。
- 终于是摸到了问题所在,因为多网卡的关系,centos7会选择默认路由接收udp组播,但是我的默认路由所属网卡是ens37!!所以我就将默认路由换一下试试
# 删除路由
ip route del default via 路由地址
# 新增路由
ip route add default via 路由地址
# 这是我原来的路由表
0.0.0.0 via 192.168.100.1 dev ens33
default via 192.168.1.1 dev ens37
# 操作
ip route del default via 192.168.1.1
ip route del default via 192.168.100.1
# 修改之后的路由表
0.0.0.0 via 192.168.1.1 dev ens37
default via 192.168.100.1 dev ens33
- 发现还是不行,因为centos网卡做了拦截
cat /proc/sys/net/ipv4/conf/en33/rp_filter
#结果不为0
cat /proc/sys/net/ipv4/conf/all/rp_filter
#结果不为0
将这两个部分设为0
sysctl -w net.ipv4.conf.ens33.rp_filter=0
sysctl -w net.ipv4.conf.all.rp_filter=0
设置完成后发现在虚拟机上运行服务可以接收到数据了,也算是成功迈出一大步。但是服务是部署在docker中的,docker中的服务还是获取不到。
- 原因是docker的网络模式默认使用桥接,跟宿主机的网络会有隔离。为了消除这种隔离将服务运行成host网络模式,也就是在启动容器的时候不用-p做端口映射,用--net host网络模式,这样docker里面也可以获取到数据了。这个问题也就顺利解决了。
总结
真难呐,终于是解决了,写出来挺少,一点点查真是挺费劲的,主要是我没咋接触过udp,胡乱找胡乱查,还是得多学习啦!!