指定IP_MULTICAST_IF和IP_ADD_MEMBERSHIP选项时应使用IPPROTO_IP级别,而非SOL_IP。此外,UDP是无连接协议,bind
方法用于接收,而connect
方法则不需要。
以下是在我的系统中监听两个网络接口(本地环回接口和另一个接口)的接收器示例:
import socket
mgrp = '224.3.29.71'
server_address = '', 5000
listening_interfaces = '127.0.0.1', '192.168.1.3'
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind(server_address)
for interface in listening_interfaces:
mreq = socket.inet_aton(mgrp) + socket.inet_aton(interface)
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
while True:
data, addr = s.recvfrom(1024)
print(f'{addr}: {data.decode()}')
下面是一个使用IP_ADD_MEMBERSHIP在每个接口上发送消息的发送器示例:
import socket
message = b'hello, world!'
multicast_group = ('224.3.29.71', 5000)
transmitting_interfaces = '192.168.1.3', '127.0.0.1'
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
ttl = 1
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, bytes([ttl]))
for interface in transmitting_interfaces:
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(interface))
s.sendto(message, multicast_group)
运行接收器后,多次运行发送器,输出如下:
('192.168.1.3', 63854): hello, world!
('127.0.0.1', 63854): hello, world!
('192.168.1.3', 63855): hello, world!
('127.0.0.1', 63855): hello, world!
('192.168.1.3', 63856): hello, world!
('127.0.0.1', 63856): hello, world!