11

我们现有的软件会定期将 UDP 数据包广播到本地子网 (xxx255) 上的特定端口 (7125)。我们在 HP-UX (11.11) 上运行的监控软件能够毫无问题地接收这些数据包。但是,将监控软件移植到Linux(RHEL 6.1)后,我们发现它并没有收到广播包。tcpdump 显示到达 Linux 主机的数据包,但内核不会将它们发送到我们的软件。

我一直在使用几个 python 2.x 脚本来模拟监控软件用来测试不同场景的套接字 API 调用。如果发送方使用单播 (10.1.0.5) 而不是广播 (10.1.0.255),Linux 内核会将数据包传递给接收方软件。我已经在网上搜索了几天,没有发现任何人有同样的问题。有任何想法吗?

接收器.py

from __future__ import print_function
import socket

localHost = ''
localPort = 7125
remoteHost = '10.1.0.5'
remotePort = 19100

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((localHost, localPort))
s.connect((remoteHost, remotePort))
print('Listening on {0}:{1} for traffic from {2}:{3}'.format(localHost, localPort, remoteHost, remotePort))
data = s.recv(1024)
print('Received: {0}'.format(data))
s.close()

发件人.py

from __future__ import print_function
import socket
import time

localHost = ''
localPort = 19100
remoteHost = '10.1.0.255'
remotePort = 7125

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((localHost, localPort))
s.connect((remoteHost, remotePort))
data = 'sending this from {0}:{1} to {2}:{3}'.format(localHost, localPort, remoteHost, remotePort)
print(data)
print('2')
time.sleep(1)
print('1')
time.sleep(1)
s.send(data)
print('sent at {0}'.format(time.ctime()))
s.close()
4

1 回答 1

16

好吧,我在评论中提出了这个答案,并在实践中证明是正确的。我想用我自己的代码进一步调查周围的细微差别,但这是规范的案例更接近。

除了SO_BROADCAST在两边设置套接字选项(正如您已经正确地做的那样),您还必须将您的接收器绑定到广播地址(例如,INADDR_BROADCAST它是 255.255.255.255 并且基本上起到与单播相同的作用INADDR_ANY)。

显然,在原始海报的 HP-UX 配置中,绑定到单播地址(或者INADDR_ANY,具体而言)但SO_BROADCAST设置了套接字选项的 UDP 套接字仍将接收寻址到本地广播地址的所有 UDP 数据报以及定向的单播流量在主机。

在 Linux 下,情况并非如此。绑定 UDP 套接字,即使SO_BROADCAST启用了,INADDR_ANY也不足以在绑定端口上接收单播和广播数据报。可以为广播流量使用单独的INADDR_BROADCAST绑定SO_BROADCAST套接字。

于 2012-12-03T01:26:03.600 回答