在我工作的一个系统上,良好的 ol' netstat 显示多播组成员信息,并且 ss 缺少一些信息。我想知道为什么。例如:
[root@myhost ~]# netstat -gn | egrep "Inter|239.192"
Interface RefCnt Group
em4.204 1 239.192.33.183
em1.16 2 239.192.35.1
em1.16 2 239.192.12.98
em1.16 1 239.192.32.1
[root@myhost ~]# ss -apu | egrep "State|239.192"
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 239.192.35.1:12965 *:*
UNCONN 0 0 239.192.12.98:12965 *:*
UNCONN 0 0 239.192.35.1:12965 *:*
UNCONN 0 0 239.192.12.98:12965 *:*
请注意,ss 仅显示 RefCnt 为 2 的那些组。
从技术上来说,
ip maddr show
是netstat -gn
的替代品,但它不包含RefCnt,而且它的输出也比较麻烦。另外,我们对 ss 更详细的输出感兴趣,其中可以包括侦听进程的 PID(此处未看到,因为当前没有进程实际上正在侦听多播,如 netstat -ulpn
所示:
[root@myhost ~]# netstat -ulpn | egrep "Proto|239.192"
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 239.192.35.1:12965 0.0.0.0:* -
udp 4480 0 239.192.12.98:12965 0.0.0.0:* -
udp 0 0 239.192.35.1:12965 0.0.0.0:* -
udp 0 0 239.192.12.98:12965 0.0.0.0:* -
(我遇到这个问题正在寻找类似问题的答案,即如何列出加入特定多播组的进程......)
netstat -gn
和 ip maddr
显示网络接口加入的多播组,这大致意味着发往该地址的数据包将在该接口上被接受。
netstat -nau | grep (…)
和ss -au src 224.0.0.0/4
(注意ss
中的奇特过滤器)将显示绑定到多播地址的套接字。
这是两个不同且有些无关的事情。
只需将套接字绑定到多播地址,使其显示在
ss
/ netstat
中就可以了,但它不会 自动加入多播组。
尝试:socat udp4-l:12345,bind=239.1.2.3 -
,它在 netstat 中显示为:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 239.1.2.3:12345 0.0.0.0:* 7604/socat
并且这种连接在有人加入群组之前是完全没有用的 – netstat -g
和
ip maddr
不要提及这个地址。
接收组播消息不需要绑定组播地址。
试试这个:socat udp4-listen:12345,ip-add-membership=239.1.2.3:br0 -
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:12345 0.0.0.0:* 6132/socat
收到第一条消息后,您将显示为:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 10.0.0.2:12345 10.0.0.3:52036 ESTABLISHED 6132/socat
请注意,尽管多播运行得很好,但套接字描述中没有提及您加入的多播组。
要查看多播组,您可以使用netstat -g
IPv6/IPv4 Group Memberships
Interface RefCnt Group
--------------- ------ ---------------------
br0 1 239.1.2.3
或ip maddr
:
7: br0
link 01:00:5e:01:02:03
inet 239.1.2.3
(此处仅显示相关行。)加入多播组的API实际上是设置一个套接字选项“IP_ADD_MEMBERSHIP”。要获取多播消息,必须批处理以下两件事:① 套接字绑定的端口(如
bind(…)
函数中),以及 ② IP 指定接口上任何已加入的组。(上面的 socat 使用 UDP 的伪连接模式;您还可以尝试无连接模式,例如
socat UDP-DATAGRAM:10.0.0.4:3000,bind=10.0.0.2:2000,ip-add-membership=239.1.2.3:br0 -
发送到 10.0.0.4:3000 并在 10.0.0.2:2000 和 239.1.2.3:2000%br0 上接收,并且始终显示为第一个 netstat 输出)
ip maddr
中看到使用计数:
7: br0
link 01:00:5e:01:02:03 users 2
inet 239.1.2.3 users 2
这意味着它现在显示大于 1 的 RefCnt。(您可能需要reuseaddr选项来使用socat进行测试。)