IPPROTO_RM在accept调用期间阻塞

9
这个问题类似于https://stackoverflow.com/questions/11650328/using-reliable-multicast-pragmatic-general-multicast-not-returning-from-accept,但我的代码与它略有不同,因此可能会得到不同的答案。
我正在尝试建立一个可靠的多播服务器/客户端概念验证。解决方案本身是一个服务器/客户端连接。客户端通过TCP/IP连接到服务器。然后,服务器打开一个可靠的多播套接字供客户端侦听。客户端通过TCP发送消息,服务器通过IPPROTO_RM将其回显。最终目标是让许多客户端连接到服务器,所有客户端都接收到每个回显消息。
示例代码基于此page
我已经类似地设置了我的RM套接字(请参见下面的列表)。TCP套接字正常工作。问题出在RM套接字上。服务器打开多播套接字,然后正确地绑定和连接到多播地址。然而,客户端正确地侦听,但调用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;
1个回答

1
你是否安装了MSMQ(Microsoft Message Queuing)?这是在基于Microsoft的计算机上使用IPPROTO_RM所必需的。此外,它只适用于Windows版本>= Xp || 2003。
编辑:我看到你已经检查过了。

没错,我确实检查过了。MSMQ已安装,多播支持也已安装。所有服务器都是Windows 2008。 - Anthony
是的,问题在于接收方执行accept()同步,并且直到第一条数据被接收才会返回。我目前正在寻找解决方法,也许可以使用AcceptEx()或其他方式来解决这个设计上的问题。 - RobertH
@RobertH 我认真看了一下你交换机的规格。即使我只是在本地主机上发送/接收,似乎仍然会向带有多播标志的交换机发送网络数据包。这导致整栋楼(约1000台PC)都被多播数据包淹没,这并不是我想要的结果,虽然很有趣。 - Anthony
@anthony-arnold: 交换机的行为没有问题,符合预期。即使多播服务器和客户端进程在同一主机上运行,多播服务器数据也会发送到主机外部,这是多播协议的规定。可能存在子网/建筑物之外的多播接收器,因此需要将多播数据发送到主机外部。当交换机接收到多播流量时,根据配置会洪泛或丢弃它。大多数交换机都会洪泛。 - leodotcloud
@MuraliPaluru 是的,关键是需要配置交换机以处理PGM流量而不会造成洪泛,而交换机无法配置到那个级别也并不罕见。 - Anthony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接