组播监听和接口IP地址变化
Multicast listening and interface IP address change
我正在绑定一个多播组和端口来侦听多播流。由于添加组成员(通过 IP_ADD_MEMBERSHIP)需要指定特定的网络接口,当该接口 IP 地址更改时会发生什么情况?
我是否已重新开始使用新套接字并添加会员资格?这与Linux/C环境有关。我确实看到一些数据包在没有更改 IP 的情况下进入,但我觉得我必须重新启动。
谢谢,
gl
我认为您不必重新加入群组。本地主机和路由器都只有成员计数,在这两种情况下,如果它不为零,它将在内部传送多播。但我可能是错的。
Linux 内核似乎是根据接口标识符而不是接口 IP 地址来跟踪接口。从几个实验来看,您的应用程序似乎不需要任何特殊处理
实验一:主机接收
这是我与 Ubuntu 一起进行的实验,用于测试主机是否会继续通过接口接收 IP 更改。
$ uname -a
$ Linux joel-VirtualBox 3.16.0-34-generic #47-Ubuntu SMP Fri Apr 10 18:02:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
我有一个简单的 Python 测试脚本,用于 运行 网络接口 eth2 上的多播接收器,由静态 IP 192.168.33.11 识别:
import socket
import struct
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP )
sock.bind( ('',50400) )
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton('239.254.2.4') + socket.inet_aton('192.168.33.11') )
while True:
print sock.recv( 2048 )
sock.close( sock )
一旦 运行 python 脚本,我可以通过 运行:
验证成员资格
$ netstat -gn
lo 1 224.0.0.1
eth0 1 224.0.0.251
eth0 1 224.0.0.1
eth1 1 224.0.0.1
eth2 1 224.0.0.251
eth2 1 239.254.2.4
eth2 1 224.0.0.1
从另一台 PC,我 运行 一个多播发送者,发送到 239.254.2.4:50400 并验证数据已打印。然后我将静态 IP 更改为 192.168.33.12 并验证 netstat 仍然报告成员资格并且我的 python 脚本可以继续接收数据。
实验 2:IGMP 成员报告
我进行了另一个实验以查看 IGMP 成员报告发生了什么:
如您所见,当 IP 地址发生更改时,没有为 239.254.2.4 生成新的 IGMP 报告。但是当脚本被杀死时,会发送一个 IGMP 离开消息。
尽管任何执行 IGMP 侦听或多播路由的交换机或路由器都会定期发出 IGMP 查询,但可以考虑 "a hole"。我们的主机将通过发送其当前成员资格(包括 239.254.2.4 的成员资格)来响应此查询。
我正在绑定一个多播组和端口来侦听多播流。由于添加组成员(通过 IP_ADD_MEMBERSHIP)需要指定特定的网络接口,当该接口 IP 地址更改时会发生什么情况?
我是否已重新开始使用新套接字并添加会员资格?这与Linux/C环境有关。我确实看到一些数据包在没有更改 IP 的情况下进入,但我觉得我必须重新启动。
谢谢, gl
我认为您不必重新加入群组。本地主机和路由器都只有成员计数,在这两种情况下,如果它不为零,它将在内部传送多播。但我可能是错的。
Linux 内核似乎是根据接口标识符而不是接口 IP 地址来跟踪接口。从几个实验来看,您的应用程序似乎不需要任何特殊处理
实验一:主机接收
这是我与 Ubuntu 一起进行的实验,用于测试主机是否会继续通过接口接收 IP 更改。
$ uname -a
$ Linux joel-VirtualBox 3.16.0-34-generic #47-Ubuntu SMP Fri Apr 10 18:02:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
我有一个简单的 Python 测试脚本,用于 运行 网络接口 eth2 上的多播接收器,由静态 IP 192.168.33.11 识别:
import socket
import struct
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP )
sock.bind( ('',50400) )
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton('239.254.2.4') + socket.inet_aton('192.168.33.11') )
while True:
print sock.recv( 2048 )
sock.close( sock )
一旦 运行 python 脚本,我可以通过 运行:
验证成员资格$ netstat -gn
lo 1 224.0.0.1
eth0 1 224.0.0.251
eth0 1 224.0.0.1
eth1 1 224.0.0.1
eth2 1 224.0.0.251
eth2 1 239.254.2.4
eth2 1 224.0.0.1
从另一台 PC,我 运行 一个多播发送者,发送到 239.254.2.4:50400 并验证数据已打印。然后我将静态 IP 更改为 192.168.33.12 并验证 netstat 仍然报告成员资格并且我的 python 脚本可以继续接收数据。
实验 2:IGMP 成员报告
我进行了另一个实验以查看 IGMP 成员报告发生了什么:
如您所见,当 IP 地址发生更改时,没有为 239.254.2.4 生成新的 IGMP 报告。但是当脚本被杀死时,会发送一个 IGMP 离开消息。
尽管任何执行 IGMP 侦听或多播路由的交换机或路由器都会定期发出 IGMP 查询,但可以考虑 "a hole"。我们的主机将通过发送其当前成员资格(包括 239.254.2.4 的成员资格)来响应此查询。