Multicasting (and broadcasting which is also discussed in this article)
provides a means to direct a single packet to more than one host. Special
addresses are defined for this purpose and are handled specially by network
adapters, networking hardware, and IP stacks.
多播(以及本文中讨论的广播)提供了一种将单个数据包定向到多个主机的方法。为此目的定义了特殊地址,并由网络适配器、网络硬件和 IP 栈特殊处理。
IPv4 specifications provide broadcasting and multicasting; IPv6 provides
multicasting but replaces broadcasting by special multicast modes. UNIX domain
sockets do not know broadcasting or multicasting.
IPv4 规范提供了广播和多播;IPv6 提供了多播,但通过特殊的多播模式替代了广播。UNIX 域套接字不了解广播或多播。
The following examples use UDP/IPv4 only. However, they can easily be
adapted for raw IPv4 sockets. IPv6 multicasting has not yet been successfully
used with socat; please contact the author if you have positive experiences or
ideas that go beyond IPV6_ADD_MEMBERSHIP.
以下示例仅使用 UDP/IPv4。但是,它们可以很容易地适应原始 IPv4 套接字。IPv6 多播尚未成功地与 socat 一起使用;如果您有积极的经验或超出 IPV6_ADD_MEMBERSHIP 的想法,请与作者联系。
All multicast examples presented in this document use multicast address
224.1.0.1; it can be replaced by any valid IPv4 multicast address (except
all-systems).
本文档中提供的所有组播示例均使用组播地址 224.1.0.1;可以用任何有效的 IPv4 组播地址(除了 all-systems)替换它。
We assume a local network with address 192.168.10.0 and mask 255.255.255.0; an
eventual "client" has 192.168.10.1, example "server" and example peer have
192.168.10.2 in all examples. Change these addresses and mask to your own
requirements.
我们假设一个具有地址 192.168.10.0 和掩码 255.255.255.0 的本地网络;一个可能的“客户端”具有 192.168.10.1,示例“服务器”和示例对等体在所有示例中均具有 192.168.10.2。将这些地址和掩码更改为符合您需求的内容。
All the following examples work bidirectionally except when otherwise noticed.
For "clients" we just use STDIO, and for "servers" we use EXEC:hostname which
ingores its input but shows us which host the reply comes from. Replace these
socat addresses with what is appropriate for your needs (e.g. shell script
invocations). Port 6666 can be replaced with any other port (but for ports <
1024 root privilege might be required).
除非另有通知,所有以下示例均可双向工作。对于“客户端”,我们只使用 STDIO ,对于“服务器”,我们使用 EXEC:hostname ,它忽略其输入但显示我们收到回复的主机。将这些 socat 地址替换为适合您需求的内容(例如,shell 脚本调用)。端口 6666 可以替换为任何其他端口(但对于端口<1024,可能需要 root 权限)。
Different kinds of broadcast addresses exist: 255.255.255.255 is local network
only; for the IPv4 network 192.168.10.0/24 the "official" broadcast address
is 192.168.10.255; the network address 192.168.10.0 is also interpreted as
broadcast by some hosts. The two latter forms are routed by gateways. In the
following examples we only use broadcast address 192.168.10.255.
存在不同类型的广播地址:255.255.255.255 仅用于本地网络;对于 IPv4 网络 192.168.10.0/24,"官方" 广播地址是 192.168.10.255;网络地址 192.168.10.0 也被一些主机解释为广播。后两种形式由网关路由。在以下示例中,我们仅使用广播地址 192.168.10.255。
This example builds something like a "supervisor" or "client" that
communicates with a set of "servers". The supervisor may send packets to the
multicast address, and the servers may send response packets. Note that the
servers would also respond to other clients' requests.
此示例构建类似于“监督员”或“客户端”的东西,它与一组“服务器”通信。监督员可以向多播地址发送数据包,服务器可以发送响应数据包。请注意,服务器也会响应其他客户端的请求。
Multicast server: 多播服务器:
socat UDP4-RECVFROM:6666,ip-add-membership=224.1.0.1:192.168.10.2,fork EXEC:hostname
This command receives multicast packets addressed to 224.1.0.1 and forks a
child process for each. The child processes may each send one or more reply
packets back to the particular sender. 192.168.10.2 means the address of the
interface where multicasts should be received.
Run this command on a number of hosts, and they will all respond in
parallel.
此命令接收寻址为 224.1.0.1 的多播数据包,并为每个数据包派生一个子进程。子进程可以向特定发送者发送一个或多个回复数据包。192.168.10.2 表示应接收多播的接口地址。在多台主机上运行此命令,它们将并行响应。
Multicast client: 多播客户端:
socat STDIO UDP4-DATAGRAM:224.1.0.1:6666,range=192.168.10.0/24
This process transfers data from stdin to the multicast address, and transfers
packets received from the local network to stdout. It does not matter in which
direction the first data is passed.
A packet from the network is accepted by the IP stack for our socket if:
此过程将数据从标准输入传输到多播地址,并将从本地网络接收到的数据包传输到标准输出。第一批数据传递的方向并不重要。如果网络中的数据包被我们的套接字接受,则会被 IP 栈接受。
Broadcast server: 广播服务器:
socat UDP4-RECVFROM:6666,broadcast,fork EXEC:hostname
This command receives packets addressed to a local broadcast address and forks
a child process for each. The child processes may each send one or more reply
packets back to the particular sender.
Run this command on a number of hosts, and they will all respond in
parallel.
此命令接收发送到本地广播地址的数据包,并为每个数据包创建一个子进程。每个子进程可以向特定发送方发送一个或多个回复数据包。在多台主机上运行此命令,它们将并行响应。
Broadcast client: 广播客户端:
socat STDIO UDP4-DATAGRAM:192.168.10.255:6666,broadcast,range=192.168.10.0/24
This process transfers data from stdin to the broadcast address, and transfers
packets received from the local network to stdout. It does not matter in which
direction the first data is passed.
A packet from the network is accepted by the IP stack for our socket if:
此过程将数据从标准输入传输到广播地址,并将从本地网络接收到的数据包传输到标准输出。第一批数据传输的方向并不重要。如果网络中的数据包满足以下条件,则会被 IP 栈接受到我们的套接字中:
The broadcast option is only required for sending or receiving
local broadcasts.
“ broadcast ”选项仅在发送或接收本地广播时才需要。
It is possible to combine multicast sender and receiver in one socat
address. This allows to start processes on different hosts on the local network
that will communicate symmetrically, so each process can send messages that are
received by all the other ones.
可以将多播发送器和接收器组合在一个 socat 地址中。这样可以在本地网络上的不同主机上启动进程,使它们可以对称通信,因此每个进程都可以发送消息,而所有其他进程都会接收到这些消息。
This command is valid for host 192.168.10.2; adapt this address to the
particular interface addresses of the hosts.
此命令适用于主机 192.168.10.2;请根据主机的特定接口地址调整此地址。
Starting this process opens a socket on port 6666 that will receive packets
directed to multicast address 224.1.0.1. Only packets with matching source
address and source port 6666 will be handled though. When this process sends
data to the network the packets will be addressed to 224.1.0.1:6666 and have a
source address of 192.168.10.2:6666, matching the accept criteria of the peers
on the local network.
启动此过程会在端口 6666 上打开一个套接字,用于接收定向到多播地址 224.1.0.1 的数据包。只有源地址和源端口为 6666 的数据包才会被处理。当此过程向网络发送数据时,数据包将被寻址为 224.1.0.1:6666,并具有源地址 192.168.10.2:6666,符合本地网络上对等体的接受标准。
Note: this command receives the packets it just has sent; add option
ip-multicast-loop=0 if this in undesired.
注意:此命令接收它刚刚发送的数据包;如果这是不希望的,请添加选项 ip-multicast-loop=0 。
Just as with multicast, it is possible to combine broadcast sender and
receiver in one socat address.
就像多播一样,可以在一个 socat 地址中组合广播发送器和接收器。
Starting this process opens a socket on port 6666 that will receive packets
directed to a local broadcast addresses. Only packets with matching source
address and source port 6666 will be handled though. When this process sends
data to the network the packets will be addressed to 255.255.255.255:6666 and
have a source address of 192.168.10.2:6666, matching the accept criteria of
the peers on the local network.
启动此进程会在端口 6666 上打开一个套接字,用于接收定向到本地广播地址的数据包。但只有源地址和源端口为 6666 的数据包才会被处理。当此进程向网络发送数据时,数据包将被寻址为 255.255.255.255:6666,并具有源地址 192.168.10.2:6666,与本地网络上的对等方的接受标准相匹配。
Note: this command receives the packets it just has sent; there does not
seem to exist a simple way to prevent this.
注意:此命令接收它刚刚发送的数据包;似乎没有简单的方法来阻止这种情况发生。
If you do not get an error message during operation, but the packets do not
reach the target processes, use tcpdump to see if the packets have the
correct source and destination addresses and ports, and if they leave and enter
the hosts as expected.
如果在操作过程中没有收到错误消息,但数据包未到达目标进程,请使用 tcpdump 查看数据包是否具有正确的源和目标地址和端口,并且它们是否按预期离开和进入主机。
The following subsections discuss some typical sources of trouble.
下面的小节讨论了一些典型的故障源。
If you do not succeed in receiving multicast or broadcast packets, check if
iptables are activated on the receiving or sending host. They might be
configured to disallow this traffic.
如果您无法接收多播或广播数据包,请检查接收或发送主机上是否激活了 iptables。它们可能被配置为禁止此流量。
When using multicast communications, you should not bind the sockets to a
specific IP address. It seems that the (Linux) IP stack compares the
destination address with the bind address, not taking care of the multicast
property of the incoming packet.
在使用多播通信时,不应将套接字绑定到特定的 IP 地址。似乎(Linux)IP 栈将目标地址与绑定地址进行比较,而不考虑传入数据包的多播属性。
When you receive an error like:
当您收到类似错误时:
... E sendto(3, 0x80c2e44, 4, 0, AF=2 224.1.0.1:6666, 16): Network is unreachable |
you have a routing problem. The (Linux) IP stack seems to handle multicast
addresses just like unicast addresses when determining their route (interface
and gateway), i.e. the routing table needs an entry that somehow matches the
target address.
您可能遇到了路由问题。 (Linux) IP 栈在确定多播地址的路由(接口和网关)时似乎与单播地址一样处理,即路由表需要有一个条目与目标地址匹配。
For the same reason, multicast packets will probably leave your host on the
interface with the default route if it is specified.
出于同样的原因,如果指定了默认路由,多播数据包可能会通过您的主机上的接口离开。
Set a multicast/broadcast route with the following command (Linux):
使用以下命令设置多播/广播路由(Linux):
224.0.0.1 is the all-systems multicast address: all
datagram sockets appear to be automatically member of this group on all
interfaces. This membership cannot be dropped on Linux (you need iptables to
filter packets).
224.0.0.1 是所有系统的多播地址:所有数据报套接字似乎自动成为此组的成员,出现在所有接口上。在 Linux 上无法取消此成员身份(您需要使用 iptables 来过滤数据包)。
When you use the above examples you should understand that all datagram
sockets without exception accept all packets that are directly addressed to
them;
the multi- and broadcast receiving features are just extensions to this
functionality. socat currently has no means to handle incoming packets
differently whether they are addressed to unicast, multicast, or broadcast
addresses. However, for EXEC'd scripts socat can provide this info in
environment variables.
当您使用上述示例时,应了解所有数据报套接字无一例外地接受所有直接寻址到它们的数据包;多播和广播接收功能只是此功能的扩展。socat 目前无法处理传入数据包的方式,无论它们是寻址到单播、多播还是广播地址。但是,对于执行的脚本,socat 可以在环境变量中提供此信息。
Authentication or encryption are not available.
认证或加密不可用。
It is very easy to fake the source address of UDP (or raw IP) packets. You
should understand whether your network is protected from address spoofing
attacks.
很容易伪造 UDP(或原始 IP)数据包的源地址。您应该了解您的网络是否受到地址欺骗攻击的保护。
Broadcast and multicast traffic can trivially be received by any
host on the local network.
广播和组播流量可以轻松地被本地网络上的任何主机接收。
These modes already enable several different client/server oriented operations.
Moreover, the SENDTO addresses can send to multicast and broadcast addresses
(the latter requires the broadcast option though). RECV and RECVFROM
also would accept packets addressed to a local broadcast address (with option
broadcast) or the all-systems multicast address.
这些模式已经可以实现多种不同的客户端/服务器操作。此外,SENDTO 地址可以发送到多播和广播地址(后者需要 broadcast 选项)。RECV 和 RECVFROM 也可以接收发送到本地广播地址的数据包(使用选项 broadcast )或所有系统的多播地址。
These address types had, however, two major caveats:
这些地址类型有两个主要的注意事项:
socat version 1.6.0 addresses these problems and provides a new more generic
datagram address type (*-DATAGRAM) and the new address option IP-ADD-MEMBERSHIP.
socat 版本 1.6.0 解决了这些问题,并提供了一个新的更通用的数据报地址类型 (*-DATAGRAM) 和新的地址选项 IP-ADD-MEMBERSHIP。
Please note that multicasting on IPv6 requires a patch that has been
introduced past version 1.7.3.2! Use option like
ipv6-join-group=[ff02::d]:eth0.
请注意,IPv6 上的多播需要一个补丁,该补丁在版本 1.7.3.2 之后引入!使用选项如 ipv6-join-group=[ff02::d]:eth0 。
socat version 1.7.0 helps to find more information about incoming packets in
environment variables that can be used in scripts or programs invoked by
socat. The option ip-pktinfo (on non-BSD systems)
or ip-recvdstaddr (on BSD systems) is required to get basic
information about incoming packets.
socat 版本 1.7.0 帮助查找有关传入数据包的更多信息,这些信息可以在由 socat 调用的脚本或程序中使用环境变量。选项 ip-pktinfo (在非 BSD 系统上)或 ip-recvdstaddr (在 BSD 系统上)需要获取有关传入数据包的基本信息。
Example: Start a receiver of the following form (tried on Linux):
示例:启动以下形式的接收器(在 Linux 上尝试):
Then send a multicast packet from the client:
然后从客户端发送一个多播数据包:
On the server the following text should appear (only interesting lines shown):
在服务器上应该显示以下文本(仅显示有趣的行):
export SOCAT_IP_DSTADDR="224.1.0.1" export SOCAT_IP_IF="eth0" export SOCAT_IP_LOCADDR="192.168.10.2" export SOCAT_PEERADDR="192.168.10.1" export SOCAT_PEERPORT="41159"
SOCAT_IP_IF shows the interface where the packet entered the server;
SOCAT_IP_LOCADDR shows the IP address of this interface;
SOCAT_IP_DSTADDR shows the target address of the packet;
SOCAT_PEERADDR and SOCAT_PEERPORT are the client socket
values.
SOCAT_IP_IF 显示数据包进入服务器的接口; SOCAT_IP_LOCADDR 显示此接口的 IP 地址; SOCAT_IP_DSTADDR 显示数据包的目标地址; SOCAT_PEERADDR 和 SOCAT_PEERPORT 是客户端套接字的值。
This document was last modified in May 2009.
该文档最后修改于 2009 年 5 月。
Copyright: Gerhard Rieger 2007-2009
版权所有:Gerhard Rieger 2007-2009
License: GNU Free Documentation License (FDL)
许可证:GNU 自由文档许可证(FDL)