PGM 发送方和接收方
建立 PGM 会话类似于与 TCP 会话关联的连接建立例程。 但是,与 TCP 会话的重大不同是客户端和服务器语义是相反的;PGM 发送方 (服务器) 连接到多播组,而客户端 (PGM 接收方) 等待接受连接。 以下段落详细介绍了创建 PGM 发送方和 PGM 接收方所需的编程步骤。 本页还介绍 PGM 会话的可用数据模式。
PGM 发送方
若要创建 PGM 发送方,请执行以下步骤
不对任何客户端执行正式会话握手。 连接过程类似于 UDP 连接,因为它将多播组) (终结点地址与套接字相关联。 完成后,可以在套接字上发送数据。
当发送方创建 PGM 套接字并将其连接到多播地址时,将创建 PGM 会话。 可靠的多播会话由全局唯一标识符 (GUID) 和源端口的组合定义。 GUID 由传输生成。 sSource 端口由传输指定,并且不会提供对使用哪个源端口的控制。
注意
不允许在发送方套接字上接收数据,并导致错误。
以下代码片段演示了如何设置 PGM 发送方:
SOCKET s;
SOCKADDR_IN salocal, sasession;
int dwSessionPort;
s = socket (AF_INET, SOCK_RDM, IPPROTO_RM);
salocal.sin_family = AF_INET;
salocal.sin_port = htons (0); // Port is ignored here
salocal.sin_addr.s_addr = htonl (INADDR_ANY);
bind (s, (SOCKADDR *)&salocal, sizeof(salocal));
//
// Set all relevant sender socket options here
//
//
// Now, connect <entity type="hellip"/>
// Setting the connection port (dwSessionPort) has relevance, and
// can be used to multiplex multiple sessions to the same
// multicast group address over different ports
//
dwSessionPort = 0;
sasession.sin_family = AF_INET;
sasession.sin_port = htons (dwSessionPort);
sasession.sin_addr.s_addr = inet_addr ("234.5.6.7");
connect (s, (SOCKADDR *)&sasession, sizeof(sasession));
//
// We're now ready to send data!
//
PGM 接收器
若要创建 PGM 接收器,请执行以下步骤
- 创建 PGM 套接字。
- 将套接字绑定到发送方正在传输的多播组地址。
- 调用套接字上的 listen 函数,将套接字置于侦听模式。 当在指定的多播组地址和端口上检测到 PGM 会话时,侦听函数将返回 。
- 调用 accept 函数以获取与会话对应的新套接字句柄。
只有原始 PGM 数据 (ODATA) 才会触发接受新会话。 因此,传输可能会接收其他 PGM 流量 (,例如 SPM 或 RDATA 数据包) ,但不会导致 侦听 函数返回。
接受会话后,返回的套接字句柄用于接收数据。
注意
不允许在接收套接字上发送数据,这会导致错误。
以下代码片段演示了如何设置 PGM 接收器:
SOCKET s,
sclient;
SOCKADDR_IN salocal,
sasession;
int sasessionsz, dwSessionPort;
s = socket (AF_INET, SOCK_RDM, IPPROTO_RM);
//
// The bind port (dwSessionPort) specified should match that
// which the sender specified in the connect call
//
dwSessionPort = 0;
salocal.sin_family = AF_INET;
salocal.sin_port = htons (dwSessionPort);
salocal.sin_addr.s_addr = inet_addr ("234.5.6.7");
bind (s, (SOCKADDR *)&salocal, sizeof(salocal));
//
// Set all relevant receiver socket options here
//
listen (s, 10);
sasessionsz = sizeof(sasession);
sclient = accept (s, (SOCKADDR *)&sasession, &sasessionsz);
//
// accept will return the client socket and we are now ready
// to receive data on the new socket!
//
数据模式
PGM 会话有两种数据模式选项:消息模式和流模式。
消息模式适用于需要发送离散消息的应用程序,并且由 SOCK_RDM 套接字类型指定。 流模式适用于需要将流式处理数据发送到接收方的应用程序,例如视频或语音应用程序,并且由套接字类型SOCK_STREAM指定。 模式的选择会影响 Winsock 处理数据的方式。
请考虑以下示例:消息模式 PGM 发送方对 WSASend 函数进行三次调用,每个调用具有 100 字节缓冲区。 此操作在网络上显示为三个离散 PGM 数据包。 在接收方,每次调用 WSARecv 函数仅返回 100 个字节,即使提供了更大的接收缓冲区。 相比之下,使用流模式 PGM 发送方时,这三个 100 字节的传输可以合并成网络上少于三个物理数据包, (或合并为接收方) 的一个数据 blob。 因此,当接收方调用其中一个 Windows 套接字接收函数时,PGM 传输收到的任意数据量都可以返回到应用程序,而不考虑数据的物理传输或接收方式。