mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-26 23:01:04 +08:00
179 lines
6.3 KiB
Plaintext
179 lines
6.3 KiB
Plaintext
= zmq_pgm(7)
|
|
|
|
|
|
== NAME
|
|
zmq_pgm - 0MQ reliable multicast transport using PGM
|
|
|
|
|
|
== SYNOPSIS
|
|
PGM (Pragmatic General Multicast) is a protocol for reliable multicast
|
|
transport of data over IP networks.
|
|
|
|
|
|
== DESCRIPTION
|
|
0MQ implements two variants of PGM, the standard protocol where PGM datagrams
|
|
are layered directly on top of IP datagrams as defined by RFC 3208 (the 'pgm'
|
|
transport) and "Encapsulated PGM" or EPGM where PGM datagrams are encapsulated
|
|
inside UDP datagrams (the 'epgm' transport).
|
|
|
|
The 'pgm' and 'epgm' transports can only be used with the 'ZMQ_PUB' and
|
|
'ZMQ_SUB' socket types.
|
|
|
|
Further, PGM sockets are rate limited by default. For details, refer to the
|
|
'ZMQ_RATE', and 'ZMQ_RECOVERY_IVL' options documented in
|
|
xref:zmq_setsockopt.adoc[zmq_setsockopt]
|
|
|
|
CAUTION: The 'pgm' transport implementation requires access to raw IP sockets.
|
|
Additional privileges may be required on some operating systems for this
|
|
operation. Applications not requiring direct interoperability with other PGM
|
|
implementations are encouraged to use the 'epgm' transport instead which does
|
|
not require any special privileges.
|
|
|
|
|
|
== ADDRESSING
|
|
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
|
|
'address'. The 'transport' specifies the underlying protocol to use. The
|
|
'address' specifies the transport-specific address to connect to.
|
|
|
|
For the PGM transport, the transport is `pgm`, and for the EPGM protocol the
|
|
transport is `epgm`. The meaning of the 'address' part is defined below.
|
|
|
|
|
|
Connecting a socket
|
|
~~~~~~~~~~~~~~~~~~~
|
|
When connecting a socket to a peer address using _zmq_connect()_ with the 'pgm'
|
|
or 'epgm' transport, the 'endpoint' shall be interpreted as an 'interface'
|
|
followed by a semicolon, followed by a 'multicast address', followed by a colon
|
|
and a port number.
|
|
|
|
An 'interface' may be specified by either of the following:
|
|
|
|
* The interface name as defined by the operating system.
|
|
* The primary IPv4 address assigned to the interface, in its numeric
|
|
representation.
|
|
|
|
NOTE: Interface names are not standardised in any way and should be assumed to
|
|
be arbitrary and platform dependent. On Win32 platforms no short interface
|
|
names exist, thus only the primary IPv4 address may be used to specify an
|
|
'interface'. The 'interface' part can be omitted, in that case the default one
|
|
will be selected.
|
|
|
|
A 'multicast address' is specified by an IPv4 multicast address in its numeric
|
|
representation.
|
|
|
|
|
|
== WIRE FORMAT
|
|
Consecutive PGM datagrams are interpreted by 0MQ as a single continuous stream
|
|
of data where 0MQ messages are not necessarily aligned with PGM datagram
|
|
boundaries and a single 0MQ message may span several PGM datagrams. This stream
|
|
of data consists of 0MQ messages encapsulated in 'frames' as described in
|
|
xref:zmq_tcp.adoc[zmq_tcp]
|
|
|
|
|
|
PGM datagram payload
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
The following ABNF grammar represents the payload of a single PGM datagram as
|
|
used by 0MQ:
|
|
|
|
....
|
|
datagram = (offset data)
|
|
offset = 2OCTET
|
|
data = *OCTET
|
|
....
|
|
|
|
In order for late joining consumers to be able to identify message boundaries,
|
|
each PGM datagram payload starts with a 16-bit unsigned integer in network byte
|
|
order specifying either the offset of the first message 'frame' in the datagram
|
|
or containing the value `0xFFFF` if the datagram contains solely an
|
|
intermediate part of a larger message.
|
|
|
|
Note that offset specifies where the first message begins rather than the first
|
|
message part. Thus, if there are trailing message parts at the beginning of
|
|
the packet the offset ignores them and points to first initial message part
|
|
in the packet.
|
|
|
|
The following diagram illustrates the layout of a single PGM datagram payload:
|
|
|
|
....
|
|
+------------------+----------------------+
|
|
| offset (16 bits) | data |
|
|
+------------------+----------------------+
|
|
....
|
|
|
|
The following diagram further illustrates how three example 0MQ frames are laid
|
|
out in consecutive PGM datagram payloads:
|
|
|
|
....
|
|
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) |
|
|
+--------------+----------------------------+-------------+
|
|
....
|
|
|
|
|
|
== CONFIGURATION
|
|
|
|
The PGM is protocol is capable of multicasting data at high rates (500Mbps+)
|
|
with large messages (1MB+), however it requires setting the relevant ZMQ socket
|
|
options that are documented in xref:zmq_setsockopt.adoc[zmq_setsockopt]:
|
|
|
|
* The 'ZMQ_RATE' should be set sufficiently high, e.g. 1Gbps
|
|
* The 'ZMQ_RCVBUF' should be increased on the subscriber, e.g. 4MB
|
|
* The 'ZMQ_SNDBUF' should be increased on the publisher, e.g. 4MB
|
|
|
|
It's important to note that the 'ZMQ_RCVBUF' and 'ZMQ_SNDBUF' options are
|
|
limited by the underlying host OS tx/rx buffer size limit. On linux, these can
|
|
be increased for the current session with the following commands:
|
|
|
|
....
|
|
# 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
|
|
....
|
|
|
|
|
|
== EXAMPLE
|
|
.Connecting a socket
|
|
----
|
|
// 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);
|
|
----
|
|
|
|
|
|
== SEE ALSO
|
|
* xref:zmq_connect.adoc[zmq_connect]
|
|
* xref:zmq_setsockopt.adoc[zmq_setsockopt]
|
|
* xref:zmq_tcp.adoc[zmq_tcp]
|
|
* xref:zmq_ipc.adoc[zmq_ipc]
|
|
* xref:zmq_inproc.adoc[zmq_inproc]
|
|
* xref:zmq_vmci.adoc[zmq_vmci]
|
|
* xref:zmq.adoc[zmq]
|
|
|
|
|
|
== AUTHORS
|
|
This page was written by the 0MQ community. To make a change please
|
|
read the 0MQ Contribution Policy at <https://zeromq.org/how-to-contribute/>.
|