接收 UDP 广播

Posted

技术标签:

【中文标题】接收 UDP 广播【英文标题】:Receiving UDP broadcast 【发布时间】:2012-09-20 14:37:50 【问题描述】:

我必须(在 Ubuntu 中,如果这有什么不同的话)。使用 Wireshark,我可以看到从服务器机器发送的数据包,并且我可以看到它正在被我的客户端机器接收,但我的程序完全没有注意到。这就是我所拥有的:

sockaddr_in si_me, si_other;
int s;
assert((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))!=-1);
int port=6000;
int broadcast=1;

setsockopt(s, SOL_SOCKET, SO_BROADCAST,
            &broadcast, sizeof broadcast);

memset(&si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = INADDR_ANY;

assert(::bind(s, (sockaddr *)&si_me, sizeof(sockaddr))!=-1);

while(1)

    char buf[10000];
    unsigned slen=sizeof(sockaddr);
    recvfrom(s, buf, sizeof(buf)-1, 0, (sockaddr *)&si_other, &slen);

    printf("recv: %s\n", buf);

它是在调试模式下编译的,编译过程中不会删除断言,我的程序只是阻塞在recvfrom

为了接收非目标 UDP 广播,我是否必须跳过其他任何环节?

编辑:再多一点信息,我将两台计算机连接在一个专用交换机上,没有外部干扰。我的客户端计算机上还有第二个网卡,它连接到公司网络,它也可以工作。

我可以 ping 外部(互联网工作)和我的服务器机器(而且我可以在 Wireshark 中看到实际的数据包),但你永远不知道是什么导致了这个问题。

【问题讨论】:

这段代码适用于我(经过轻微修改以使其使用 C 编译器进行编译)。 bind 可能绑定到错误的接口? netstat -an | grep 6000 在客户端机器上返回什么? 是的,它应该可以工作,但它不适合我。 netstat -an 显示没有打开的 6000 端口,我已经仔细检查过(我也尝试使用“重用”udp 标志)。 bind() 实际上并没有打开端口。只有connect()listen() 这样做。但是你不需要通过listen()打开一个端口来接收UDP广播。 @RemyLebeau 当然 bind() 打开一个端口。调用后查看 netstat 。另一方面,connect() 根本没有可见的效果。 由于 UDP 是无连接的,UDP 套接字上的connect() 仅在本地和远程 IP/端口对之间的套接字句柄内建立静态关联,仅此而已。当我提到connect() 打开一个端口时,我指的是 TCP。在 UDP 套接字上调用 bind() 会将绑定的 IP/端口添加到 netstat 列表中,但它不会显示任何状态,这可能对所有 UDP 连接都是如此。 【参考方案1】:

事实证明,我的代码完全没有问题,正如我所想的那样。网络设置本身存在问题。

为了后代,我在它们自己的集线器上设置了两台静态 IP 计算机,而不是使用服务器机器上的内置 DHCP 服务器为另一台计算机分配 IP 地址。我的问题非常本地化,但你永远不知道..

【讨论】:

【参考方案2】:

发送和接收广播

    确保网络掩码正确。在 windows 掩码中广播数据包无关紧要,但在 linux 中则不然。

    将套接字绑定到 INADDR_ANY

    setsockopt 转为广播

    使用 sendaddr.sin_addr.s_addr = inet_addr("your_interface_broadcast_address") 调用 sendto。 或 - 使用广播 IP 地址为每个接口多次调用 sendo。

    调用 recvfrom。在调用 recvfrom 之前的任何时候,设置长度参数。

【讨论】:

为什么要发这个?您可以在 2012 年的原始消息中看到我已经做到了这一点...

以上是关于接收 UDP 广播的主要内容,如果未能解决你的问题,请参考以下文章

Python网络编程—UDP套接字广播

接收 UDP 广播

udp为啥收不到广播中的数据,该怎么处理

在 C# 中接收 UDP 广播消息

LINUX SOCKET UDP C 广播问题

UDP网络程序实例