所有接口上的UDP广播

所有接口上的UDP广播

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

问题描述

在具有有线和无线接口(例如192.168.1.x和192.168.2.x子网)的Linux系统上,我要发送UDP广播,该广播通过所有可用接口(即通过有线和无线)输出无线接口).

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.255 192.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广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 05:03