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. 调用套接字上的 侦听 函数,以将套接字置于侦听模式。 侦听函数在指定的多播组地址和端口上检测到 PGM 会话时返回。
  4. 调用 接受 函数以获取与会话对应的新套接字句柄。

只有原始 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 传输接收的任何数据量都可能会返回到应用程序,而不考虑数据的物理传输方式或接收方式。