我们有现有软件将UDP数据包周期性广播到本地子网(x.x.x.255)上的特定端口(7125)。我们有在HP-UX(11.11)上运行的监控软件,能够接收这些数据包没有问题。但是,将监控软件移植到Linux(RHEL 6.1)后,我们发现它不会收到广播数据包。 tcpdump显示到达Linux主机的数据包,但内核不会将它们发送到我们的软件。在Linux上接收UDP广播数据包
我一直在使用模拟套接字API的几个python 2.x脚本来调用监视软件用来测试不同的场景。如果发送方使用单播(10.1.0.5),而不是广播(10.1.0.255),则Linux内核将数据包传递给接收方软件。我一直在网上搜索几天,并没有发现任何人有同样的问题。有任何想法吗?
receiver.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()
sender.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()
您的接收器是否需要“绑定”广播地址或“INADDR_BROADCAST”(255.255.255.255,广播的“INADDR_ANY”)?也就是说,除了设置'SO_BROADCAST'选项(双方)之外,就像你已经做的那样。您是否检查所有这些套接字系统调用的错误/返回代码? –
@MatthewHall aha,绑定到广播地址确实有效!我想这意味着Linux会让你选择单播还是广播?我们可以绑定到INADDR_ANY,并在HP-UX上接收单播和广播数据包。 – goose
是的,这似乎是你必须选择。我现在已经为你的问题发布了一个规范的答案。然而,我对Linux上的行为与HP-UX的行为有所不同有些困惑(尽管有人争辩说为什么分离广播和单播更可取)。对我而言,这表明我们并不知道所有事情,嗯,这是不可接受的。我很想用C编写一对测试程序来充实Linux上的广播选项,尽管我没有HP-UX ......在此之前,希望我的答案能够涵盖它。 –