使UDP广播与wifi路由器一起工作

Making UDP broadcast work with wifi router

我想在一个非常简单的网络上测试 UDP 广播:一个根本没有连接到互联网的旧 wifi 路由器 (WRT54GS)、一个 android 平板电脑和我的 macbook:

[Tablet] <\/\/\/\/\/> [Wifi Router] <\/\/\/\/\/> [Macbook]

其中波浪线表示无线连接。

Macbook 的 IP 地址为 192.168.1.101,平板电脑的 IP 地址为 192.168.1.102。路由器是 192.168.1.1。

为了避免过多的底层细节,我想使用 netcat 来进行测试。我决定使用端口 11011,因为它很容易输入。

作为第一步,我想我会尝试让这个工作从 macbook 恢复到它本身。在两个终端windows,我运行这些程序

Window 1: % nc -ul 11011

这是我先启动的,然后:

Window 2: % echo 'foo' | nc -v -u 255.255.255.255 11011

Window1 中没有显示任何内容。Window2 中的结果是这样的:

found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif (null)
    src 192.168.1.2 port 61985
    dst 255.255.255.255 port 11011
    rank info not available

我很确定我在这里遗漏了一些明显的东西。熟悉 nc 的人可以发现我明显的错误吗?

这是一个由多个部分组成的答案,是从其他 SO 和 SuperUser 的答案以及一些猜测中收集而来的。

Mac-to-mac 通过 wifi 上的 UDP 广播通信

首先是截至 2018 年 10 月的 mac 版本的 netcat (nc) 不支持广播,因此您必须切换到 "socat",它更通用并且它可以发送的内容很强大。至于聆听方面,最终对我有用的是

Terminal 1: % nc  -l -u 11011

发送方呢?好吧,事实证明我需要更多信息。例如,用 localhost 尝试这个根本不起作用,因为那个特定的 "interface" (天哪,我讨厌 CS 中的单词超载;作为一名数学家,我希望 CS 的人可能已经从根据我们的经验,这是个多么糟糕的主意……)不支持广播。我是怎么知道的?通过 ifconfig,一个显示您的网络配置方式的工具。在我的例子中,输出是这样的:

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
  options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
  inet 127.0.0.1 netmask 0xff000000 
  inet6 ::1 prefixlen 128 
  inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
  nd6 options=201<PERFORMNUD,DAD>
  gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
  stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  ether 98:01:a7:8a:6b:35 
  inet 192.168.1.101 netmask 0xffffff00 broadcast 192.168.1.255
  media: autoselect
  status: active
en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500
  options=60<TSO4,TSO6>
  ether 4a:00:05:f3:ac:30 
  media: autoselect <full-duplex>
  status: inactive
en2: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500
  options=60<TSO4,TSO6>
  ether 4a:00:05:f3:ac:31 
  media: autoselect <full-duplex>
  status: inactive
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=63<RXCSUM,TXCSUM,TSO4,TSO6>
  ether 4a:00:05:f3:ac:30 
  Configuration:
    id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
    maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
    root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
    ipfilter disabled flags 0x2
  member: en1 flags=3<LEARNING,DISCOVER>
        ifmaxaddr 0 port 5 priority 0 path cost 0
  member: en2 flags=3<LEARNING,DISCOVER>
        ifmaxaddr 0 port 6 priority 0 path cost 0
  media: <unknown type>
  status: inactive
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
  ether 0a:01:a7:8a:6b:35 
  media: autoselect
  status: inactive
awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484
  ether 7e:00:76:6d:5c:09 
  inet6 fe80::7c00:76ff:fe6d:5c09%awdl0 prefixlen 64 scopeid 0x9 
  nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
inet6 fe80::773a:6d9e:1d47:7502%utun0 prefixlen 64 scopeid 0xa 
nd6 options=201<PERFORMNUD,DAD>

其中大部分对我来说毫无意义。但是看看"en0",以太网连接到无线网络(192.168)。那里的数据确实能告诉你一些事情。 flags 告诉你它支持广播和多播。晚了两行,单词 broadcast 再次出现,然后是 192.168.1.255,这向我暗示这可能是向其发送广播数据包的正确地址。

考虑到这一点,我尝试了这个:

Terminal 2: % echo -n "TEST" | socat - udp-datagram:192.168.1.255:11011,broadcast

结果在1号航站楼,出现了TEST这个词!

当我在终端 2 中重新输入相同的命令时,终端 1 中什么也没有出现;似乎 "listen" 正在监听一条消息,原因我不明白。但是,嘿,至少它让我到了某个地方!

Mac 到平板电脑通信

首先,在平板电脑上,我尝试模仿上面 mac 版本的聆听端。 nc 的 termux 版本不支持 -u 标志,所以我不得不做其他事情。我决定使用socat。作为第一步,我让它工作 mac-to-mac(当然是通过 wifi 路由器)。事实证明,要侦听 UDP 数据包,您必须使用 udp-listen 而不是 udp-datagram,否则就很简单了。最后,它看起来像这样:

Terminal 1: % socat udp-listen:11011 -

意思是"listen for stuff on port 11011 and copy to standard output",

Terminal 2: % echo -n "TEST" | socat - udp-datagram:192.168.1.255:11011,broadcast

一起,这从终端 2 到终端 1 获取了数据。

然后我在平板电脑上试了一下。正如我提到的,平板电脑上的 nc 很弱。但是 socat 完全不见了。

我试了一下,发现没有安装,就安装了。

完成后,我在平板电脑上输入

Tablet: % socat udp-listen:11011 -

然后在 mac,在 2 号航站楼,我再次输入

Terminal 2: echo -n "TEST" | socat - udp-datagram:192.168.1.255:11011,broadcast

果然,TEST这个词出现在平板电脑上了!

更好的是,通过阅读我发现的文档,我可以使用

socat udp:recv:11011 -

它不仅监听,而且继续监听,因此会一个接一个地报告多个UDP数据包。 (相比之下,udp-listen 似乎等待一个数据包,然后尝试与该数据包的发送者进行通信,这根本不是我想要的。)