【问题标题】:IPPROTO_RM blocks during accept call接受调用期间的 IPPROTO_RM 阻塞
【发布时间】:2013-03-04 03:23:30
【问题描述】:

这个问题与https://stackoverflow.com/questions/11650328/using-reliable-multicast-pragmatic-general-multicast-not-returning-from-accept类似,但我的代码和它的代码略有不同,所以可能会导致不同的答案。

我正在尝试获得可靠的多播服务器/客户端概念验证设置。

解决方案本身是一个服务器/客户端连接。客户端通过 TCP/IP 连接到服务器。然后服务器打开一个可靠的多播套接字供客户端监听。客户端通过 TCP 发送消息,服务器通过IPPROTO_RM 回显它。最终目标是让许多客户端连接到服务器,所有客户端都接收每个回显的消息。

示例代码基于此page

我已经以类似方式设置了我的 RM 套接字(请参阅下面的列表)。 TCP 套接字工作正常。问题出在 RM 插座上。服务器打开多播套接字,然后将bindsconnects 正确打开到多播地址。但是,客户端 listens 正确,但对 accept 的调用会永远阻塞。

客户端和服务器进程都在同一台主机上运行。

我已检查,主机上已安装多播支持(Server 2008)。


更新:我注意到,如果我先从发送方的套接字向套接字发送一些数据,有时接受会返回。这并不理想,也不可靠。

更新:标志指向开关。似乎一个小枢纽不会削减它。我们发生了一起搞笑的事件,导致整栋楼的通讯丢失。


列表

服务器创建并连接多播发送者

short
   Port = 0;
const char
   *Address = "234.5.6.7";

SOCKET
   RMSocket;

SOCKADDR_IN 
   LocalAddr, 
   SessionAddr;

RMSocket = socket(AF_INET, SOCK_RDM, IPPROTO_RM);


if (RMSocket == INVALID_SOCKET)
   {
   return Failed;
   }

LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = htons(0);
LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);

if ( bind( RMSocket, (SOCKADDR*)&LocalAddr, sizeof(LocalAddr)) == SOCKET_ERROR )
   {
   return Failed;
   }

SessionAddr.sin_family = AF_INET;
SessionAddr.sin_port = htons( Port );
SessionAddr.sin_addr.s_addr = inet_addr( Address );

if ( connect( RMSocket, (SOCKADDR*)&SessionAddr, sizeof(SessionAddr)) == SOCKET_ERROR )
   {
   return Failed;
   }

return Success;

客户端创建并接受多播阅读器

short
   Port = 0;
const char
   *Address = "234.5.6.7";

SOCKADDR_IN 
   LocalAddr;
SOCKET
   RMListener,
   RMSocket;


RMListener = socket( AF_INET, SOCK_RDM, IPPROTO_RM );

if ( RMListener == INVALID_SOCKET ) 
   {
   return Failed;
   }


LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = htons( Port );
LocalAddr.sin_addr.s_addr = inet_addr( Address );


if ( bind( RMListener, (SOCKADDR*)&LocalAddr, sizeof(LocalAddr) ) )
   {
   return Failed;
   }


if ( listen( RMListener, SOMAXCONN ) )
   {
   return Failed;
   }

// BLOCKS HERE
RMSocket = accept( RMListener, NULL, NULL);



if ( RMSocket == INVALID_SOCKET )
   {
   return Failed;
   }

return Success;

【问题讨论】:

    标签: c multicast winsock2 reliable-multicast


    【解决方案1】:

    您是否安装了 MSMQ(微软消息队列)? IPPROTO_RM 需要在基于 Ms 的计算机上工作。此外,它仅适用于 Windows 版本 >= Xp||2003

    编辑:我看到你已经检查过了。

    【讨论】:

    • 没错,我确实查过了。 MSMQ 已安装,多播支持也已安装。所有服务器都是 Windows 2008。
    • 是的,问题是接收器执行 accept() 同步并且在收到第一个数据之前不会返回。我目前正在寻找这种设计的解决方法,可能是 AcceptEx() 或其他东西。
    • @RobertH 我会认真看看你的交换机的规格。即使我只是在本地主机上发送/接收,似乎网络数据包仍在发送到带有多播标志的交换机。这淹没了整个建筑物(大约 1000 台 PC),其中充满了发往其来源的多播数据包。有趣,但不是我真正想要的。
    • @anthony-arnold:开关的行为没有问题,预期的行为。即使多播服务器和客户端进程在同一台主机上运行,​​多播服务器的数据也会从主机发送出去,这是根据多播协议。在您的子网/建筑物之外可能有多播接收器,因此是多播数据从主机发送出去的原因。当交换机接收到多播流量时,它会根据配置对其进行泛洪或丢弃。大多数交换机都会泛滥。
    • @MuraliPaluru 是的,关键是需要配置交换机才能处理 PGM 流量而不会泛滥,并且交换机无法配置到该级别并不罕见。
    猜你喜欢
    • 1970-01-01
    • 2011-03-02
    • 2013-04-03
    • 2018-01-20
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多