在Linux上接收UDP广播数据包 [英] Receiving UDP broadcast packets on Linux

查看:1052
本文介绍了在Linux上接收UDP广播数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have existing software that periodically broadcasts UDP packets to a specific port (7125) on the local subnet (x.x.x.255). We have monitoring software running on HP-UX (11.11) that is able to receive these packets no problem. However, after porting the monitoring software to Linux (RHEL 6.1) we have found that it does not receive the broadcast packets. tcpdump shows the packets arriving at the Linux host, but the kernel does not send them through to our software.

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

I've been using a couple of python 2.x scripts that mimic the socket API calls the monitoring software uses to test different scenarios. The Linux kernel passes the packets to the receiver software if the sender uses unicast (10.1.0.5), but not broadcast (10.1.0.255). I've been searching the web for several days and have not found anyone with the same problem. Any ideas?

receiver.py

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

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()

推荐答案

好吧,我在评论中建议了这个答案,并且在实践中证明是正确的.我想用自己的代码进一步研究周围的细微差别,但这是规范的案例解答.

Well, I suggested this answer in a comment, and it proved correct in practice. I would like to investigate surrounding nuances further with my own code, but this is the canonical case-closer.

除了在两侧设置SO_BROADCAST套接字选项(如您已经正确所做的那样)之外,还必须将接收器绑定到广播地址(例如,INADDR_BROADCAST,它是255.255.255.255,实际上是与INADDR_ANY的单播角色相同.

In addition to setting the SO_BROADCAST socket option on both sides (as you are already correctly doing), you must also bind your receiver to the broadcast address (e.g., INADDR_BROADCAST, which is 255.255.255.255 and essentially serves the same role as INADDR_ANY for unicast).

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

Apparently, in the HP-UX configuration of the original poster, a UDP socket bound to a unicast address (or INADDR_ANY, specifically) but with the SO_BROADCAST socket option set will still receive all UDP datagrams addressed to the local broadcast address as well as unicast traffic directed at the host.

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

Under Linux, this is not the case. Binding a UDP socket, even when SO_BROADCAST-enabled, to INADDR_ANY is insufficient to receive both unicast and broadcast datagrams on the bound port. One can use a separate INADDR_BROADCAST-bound SO_BROADCAST socket for the broadcast traffic.

这篇关于在Linux上接收UDP广播数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆