名称

zmq_pgm - 使用 PGM 的 0MQ 可靠组播传输

概要

PGM (实用通用组播) 是一种用于通过 IP 网络可靠地组播传输数据的协议。

说明

0MQ 实现了 PGM 的两种变体:一种是标准协议,其中 PGM 数据报直接叠加在 IP 数据报之上,如 RFC 3208 所定义(即 'pgm' 传输);另一种是“封装的 PGM”或 EPGM,其中 PGM 数据报被封装在 UDP 数据报内部(即 'epgm' 传输)。

'pgm' 和 'epgm' 传输只能与 'ZMQ_PUB' 和 'ZMQ_SUB' 套接字类型一起使用。

此外,PGM 套接字默认是限速的。有关详细信息,请参阅 zmq_setsockopt 中记录的 'ZMQ_RATE' 和 'ZMQ_RECOVERY_IVL' 选项。

注意
'pgm' 传输实现需要访问原始 IP 套接字。在某些操作系统上,此操作可能需要额外的权限。不要求直接与其他 PGM 实现互操作的应用程序,建议改用不需要任何特殊权限的 'epgm' 传输。

地址

0MQ 端点是一个字符串,由一个 'transport'`://` 后跟一个 'address' 组成。'transport' 指定要使用的底层协议。'address' 指定要连接的特定于传输的地址。

对于 PGM 传输,传输方式是 pgm;对于 EPGM 协议,传输方式是 epgm。'address' 部分的含义定义如下。

连接套接字

使用 zmq_connect() 并通过 'pgm' 或 'epgm' 传输连接到对端地址时,'endpoint' 应被解释为一个 'interface' 后跟一个分号,再后跟一个 'multicast address',最后后跟一个冒号和一个端口号。

一个 'interface' 可以通过以下任一方式指定

  • 操作系统定义的接口名称。

  • 分配给接口的主要 IPv4 地址,采用数字表示形式。

注意
接口名称没有任何标准,应视为任意且取决于平台。在 Win32 平台上,不存在简短的接口名称,因此只能使用主要 IPv4 地址来指定 'interface'。'interface' 部分可以省略,在这种情况下将选择默认接口。

一个 'multicast address' 由一个 IPv4 组播地址以其数字表示形式指定。

线路格式

0MQ 将连续的 PGM 数据报解释为单个连续的数据流,其中 0MQ 消息不一定与 PGM 数据报边界对齐,并且单个 0MQ 消息可能跨越多个 PGM 数据报。此数据流由封装在“帧”中的 0MQ 消息组成,如 zmq_tcp 中所述。

PGM 数据报载荷

以下 ABNF 语法表示 0MQ 使用的单个 PGM 数据报的载荷

datagram               = (offset data)
offset                 = 2OCTET
data                   = *OCTET

为了让后期加入的消费者能够识别消息边界,每个 PGM 数据报载荷都以一个 16 位无符号整数(网络字节序)开头,该整数指定数据报中第一个消息“帧”的偏移量,如果数据报仅包含较大消息的中间部分,则该值为 0xFFFF

请注意,偏移量指定了第一个消息开始的位置,而不是第一个消息部分的开始位置。因此,如果数据包开头有消息的尾部部分,偏移量会忽略它们,并指向数据包中的第一个初始消息部分。

下图演示了单个 PGM 数据报载荷的布局

+------------------+----------------------+
| offset (16 bits) |         data         |
+------------------+----------------------+

下图进一步演示了三个示例 0MQ 帧在连续 PGM 数据报载荷中的布局方式

First datagram payload
+--------------+-------------+---------------------+
| Frame offset |   Frame 1   |   Frame 2, part 1   |
|    0x0000    | (Message 1) | (Message 2, part 1) |
+--------------+-------------+---------------------+

Second datagram payload
+--------------+---------------------+
| Frame offset |   Frame 2, part 2   |
| 0xFFFF       | (Message 2, part 2) |
+--------------+---------------------+

Third datagram payload
+--------------+----------------------------+-------------+
| Frame offset |   Frame 2, final 8 bytes   |   Frame 3   |
| 0x0008       | (Message 2, final 8 bytes) | (Message 3) |
+--------------+----------------------------+-------------+

配置

PGM 协议能够以高速率(500Mbps+)组播大消息(1MB+),但这需要设置 zmq_setsockopt 中记录的相关 ZMQ 套接字选项。

  • 'ZMQ_RATE' 应设置得足够高,例如 1Gbps

  • 订阅者应增加 'ZMQ_RCVBUF',例如 4MB

  • 发布者应增加 'ZMQ_SNDBUF',例如 4MB

重要的是要注意,'ZMQ_RCVBUF' 和 'ZMQ_SNDBUF' 选项受底层主机操作系统的发送/接收缓冲区大小限制。在 Linux 上,可以使用以下命令增加当前会话的这些限制

# set tx/rx buffers to 4MB (default can also be read as the initial buffer size)
sudo sysctl -w net.core.rmem_max=4194304
sudo sysctl -w net.core.wmem_max=4194304
sudo sysctl -w net.core.rmem_default=4194304
sudo sysctl -w net.core.wmem_default=4194304

示例

连接套接字
//  Connecting to the multicast address 239.192.1.1, port 5555,
//  using the first Ethernet network interface on Linux
//  and the Encapsulated PGM protocol
rc = zmq_connect(socket, "epgm://eth0;239.192.1.1:5555");
assert (rc == 0);
//  Connecting to the multicast address 239.192.1.1, port 5555,
//  using the network interface with the address 192.168.1.1
//  and the standard PGM protocol
rc = zmq_connect(socket, "pgm://192.168.1.1;239.192.1.1:5555");
assert (rc == 0);

另请参阅

作者

此页面由 0MQ 社区撰写。要进行更改,请阅读 0MQ 贡献政策:https://zeromq.cn/how-to-contribute/