PGM 发送方和接收方

建立 PGM 会话类似于与 TCP 会话关联的连接建立例程。 但是,与 TCP 会话的重大不同是客户端和服务器语义是相反的;PGM 发送方 (服务器) 连接到多播组,而客户端 (PGM 接收方) 等待接受连接。 以下段落详细介绍了创建 PGM 发送方和 PGM 接收方所需的编程步骤。 本页还介绍 PGM 会话的可用数据模式。

PGM 发送方

若要创建 PGM 发送方,请执行以下步骤

  1. 创建 PGM 套接字。
  2. 将套接字绑定到INADDR_ANY。
  3. 连接到 多播组传输地址。

不对任何客户端执行正式会话握手。 连接过程类似于 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 接收器,请执行以下步骤

  1. 创建 PGM 套接字。
  2. 将套接字绑定到发送方正在传输的多播组地址。
  3. 调用套接字上的 listen 函数,将套接字置于侦听模式。 当在指定的多播组地址和端口上检测到 PGM 会话时,侦听函数将返回 。
  4. 调用 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 传输收到的任意数据量都可以返回到应用程序,而不考虑数据的物理传输或接收方式。