【发布时间】:2018-09-23 22:22:39
【问题描述】:
我正在调试3rd-party network application 并试图弄清楚为什么它在使用IP_ADD_MEMBERSHIP 调用setsockopt 来设置多播组时会报告错误。该应用程序是用 C++ 编写的,但我用 python 编写了一个 MWE,它复制了相同的系统调用:
import socket
import struct
ETH0_IP = "192.168.88.85"
ETH0_1_IP = "192.168.88.254"
MULTICAST_IP = "224.0.0.7"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
ip = socket.inet_aton(ETH0_IP)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, ip)
group = struct.pack("4s4s", socket.inet_aton(MULTICAST_IP), ip)
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group)
# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
ip2 = socket.inet_aton(ETH0_1_IP)
s2.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, ip2)
group2 = struct.pack("4s4s", socket.inet_aton(MULTICAST_IP), ip2)
# the second group is added to the first socket so that we can only bind to one socket and read data from it
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group2)
在第二次IP_ADD_MEMBERSHIP 调用时,我收到错误OSError: [Errno 98] Address already in use。
我发现只有当ETH0_1_IP 是ETH_0_IP 的子接口时才会发生这种情况。而且我不确定这是否是预期的。如果是,有没有办法实际检测到这种情况并丢弃已绑定接口的子接口?此外,如果注册失败并出现上述错误,我的多播套接字是否会接收发送到子接口的数据?
为了完整起见:
$ cat /etc/network/interfaces
auto lo
iface lo inet loopback
iface lo inet6 loopback
auto eth0:1
iface eth0:1 inet static
address 192.168.88.254
netmask 255.255.240.0
【问题讨论】:
-
这是接收方代码还是发送方代码?
-
不确定,该应用程序同时具有服务器和客户端部分,但是在启动服务器时会显示此错误消息,因此我认为它应该与接收器部分连接。
-
这意味着它是一个发件人/服务器。我不是这方面的专家,但我认为您对套接字的使用可能是错误的。在这种情况下,我会查看来自 github 的一些工作,例如 github.com/hymanc/purpleproject1/blob/…、github.com/bhuztez/ercraft/blob/…、github.com/adamzfc/python_demo/blob/…,并找出做错了什么。通常可以绑定到子界面和主界面
-
我认为您可以改进您的 python 示例并使其更清晰地删除注释行并删除未使用的第二个套接字
s2。 -
据我了解,您所做的只是为现有物理适配器创建一个别名。由于这只是 Linux 的一个过时功能(在一个接口上配置多个 IP 地址),我猜测在幕后,它知道这是同一个接口,因此拒绝第二次尝试使用同一个接口。
标签: sockets networking multicast