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 套接字。
- 将套接字 绑定到发送方正在传输的多播组地址。
- 调用套接字上的 侦听 函数,以将套接字置于侦听模式。 侦听函数在指定的多播组地址和端口上检测到 PGM 会话时返回。
- 调用 接受 函数以获取与会话对应的新套接字句柄。
只有原始 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 传输接收的任何数据量都可能会返回到应用程序,而不考虑数据的物理传输方式或接收方式。