所有接口上的 UDP 广播 [英] UDP-Broadcast on all interfaces

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

问题描述

在具有有线和无线接口(例如 192.168.1.x 和 192.168.2.x 子网)的 Linux 系统上,我想发送一个通过所有可用接口(即通过有线和无线接口).

On a Linux system with a wired and a wireless interface (e.g. 192.168.1.x and 192.168.2.x subnets) I want to send a UDP broadcast that goes out via ALL available interfaces (i.e. both through the wired and the wireless interface).

目前我 sendto() 到 INADDR_BROADCAST,但似乎只通过其中一个接口发送广播(并不总是相同,后续广播可能使用另一个接口).

Currently I sendto() to INADDR_BROADCAST, however it seems that the broadcast only is sent through one of the interfaces (not always the same and subsequent broadcasts may use the other interface).

有没有一种方法可以发送通过每个接口发出的 UDP 广播?

Is there a way that I can send a UDP broadcast that goes out through every single interface?

推荐答案

首先,您应该考虑广播已过时,特别是 INADDR_BROADCAST (255.255.255.255).您的问题恰好突出了广播不合适的原因之一.它应该与 IPv4 一起消亡(希望如此).请注意,IPv6 甚至没有广播的概念(而是使用多播).

First of all, you should consider broadcast obsolete, specially INADDR_BROADCAST (255.255.255.255). Your question highlights exactly one of the reasons that broadcast is unsuitable. It should die along with IPv4 (hopefully). Note that IPv6 doesn't even have a concept of broadcast (multicast is used, instead).

INADDR_BROADCAST 仅限于本地链接.如今,它唯一可见的用途是用于 DHCP 自动配置,因为此时客户端还不知道它连接到哪个网络.

INADDR_BROADCAST is limited to the local link. Nowadays, it's only visible use is for DHCP auto-configuration, since at such time, the client will not know yet in what network it is connected to.

使用单个sendto(),只生成单个数据包,出接口由操作系统的路由表(linux上的ip route)决定.您不能让单个 sendto() 生成多个数据包,您必须遍历所有接口,并使用原始套接字或使用 setsockopt(..., SOL_SOCKET, SO_BINDTODEVICE, "ethX") 绕过操作系统路由表发送每个数据包(这需要 root 权限).不是一个好的解决方案.

With a single sendto(), only a single packet is generated, and the outgoing interface is determined by the operating system's routing table (ip route on linux). You can't have a single sendto() generate more than one packet, you would have to iterate over all interfaces, and either use raw sockets or bind the socket to a device using setsockopt(..., SOL_SOCKET, SO_BINDTODEVICE, "ethX") to send each packet bypassing the OS routing table (this requires root privileges). Not a good solution.

相反,由于 INADDR_BROADCAST 无论如何都不会被路由,因此您可以通过遍历每个接口并将数据包发送到其广播地址来实现几乎相同的目的.例如,假设您的网络有 255.255.255.0 (/24) 掩码,则广播地址为 192.168.1.255192.168.2.255.为这些地址中的每一个调用一次sendto(),您将实现目标.

Instead, since INADDR_BROADCAST is not routed anyway, you can achieve almost the same thing by iterating over each interface, and sending the packet to its broadcast address. For example, assuming that your networks have 255.255.255.0 (/24) masks, the broadcast addresses are 192.168.1.255 and 192.168.2.255. Call sendto() once for each of these addresses and you will have accomplished your goal.

修复了关于 INADDR_BROADCAST 的信息,并用关于 SO_BINDTODEVICE 的信息补充了答案.

fixed information regarding to INADDR_BROADCAST, and complementing the answer with information about SO_BINDTODEVICE.

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

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