3

这是 Windows 7 上的 C++ ......我有点像新手 Multicast Socket 人,并从其他人那里继承了这段代码。

我有这个系统,我有多台计算机在 ADDR 225.1.1.2 创建/加入多播套接字(为什么不),一旦套接字连接,它们会定期“聊天”彼此发送各种消息。如果我在网络上仅启动一台计算机(称为“A”)并让它每秒定期发送一次“keepalive”消息,但没有收到任何内容(没有其他人连接到多播地址),然后让它坐大约3分钟,然后启动另一台计算机B,第一台计算机A没有看到计算机B的广播消息!B 在发送数据包时没有出错,而 A 在接收任何内容时没有出错(从不调用接收)。如果某些东西正在关闭接收部分,我不知道如何获取通知,或者我如何注册此类信息。

如果我启动两台机器相对较近,每台机器都会看到对方的keepalive数据包。接收发生在两台机器上。但是,同样,如果我在启动第一台计算机 3 分钟后启动第二台计算机,第一台计算机的 Receive 方法似乎已经进入睡眠状态,或者消失了,或者处于昏迷状态,或者其他什么。没有产生错误,但是普通的不会看到机器 B 的数据包。(另外,我看到调试器输出中退出了 3 个线程,但它们不是我创建的线程,它们是系统线程)。但是最近启动的机器 B 确实看到了来自机器 A 的保活数据包。

这是套接字调用:

hSock = WSASocket(
    AF_INET,
    SOCK_DGRAM,
    0,
    NULL,
    0,
    WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED);

setsockopt(hSock,SOL_SOCKET,SO_REUSEADDR,(char *) &bVal,sizeof(bVal));
srcIP.sin_family=AF_INET;

// Need to bind to local interface
srcIP.sin_addr.s_addr=inet_addr(("225.1.1.2"); // htonl(INADDR_ANY);
srcIP.sin_port=htons(5555);
bind( hSock,(struct sockaddr FAR *) &srcIP,sizeof(srcIP) );

nIP_TTL=36;
setsockopt(hSock,IPPROTO_IP,IP_MULTICAST_TTL,(char *) &nIP_TTL,sizeof(int));

mreq.imr_multiaddr.s_addr=inet_addr("225.1.1.2");
mreq.imr_interface.s_addr=inet_addr("225.1.1.2");
setsockopt(hSock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &mreq,sizeof(mreq));

以下是我在网上看到的:

  1. 接收缓冲区可能已满。(我不这么认为,因为计算机 A 是网络上唯一使用多播的计算机)
  2. 防火墙可以设置为在几分钟后关闭多播接收。(我不相信这个)
  3. WinSock 协议可能会在 X 分钟不活动后关闭多播接收。(这个我也不信)
4

1 回答 1

1

我认为上面的代码有错误。我认为您必须为 imr_interface 指定计算机网络接口的本地 IP 地址(通常是计算机的 IP 地址,而不是多播地址)。也就是说,您要在其上发送/接收多播流量的接口。我假设您的代码根本没有加入多播组,它只是偶然工作了一段时间。

即使您根本没有调用 IP_ADD_MEMBERSHIP,它也可能会工作几分钟。

奇怪的 3 分钟行为听起来完全像是非工作连接或 IGMP 侦听问题。

IPv4 多播非常微妙,主机、操作系统和硬件组件之间的行为也非常微妙。

当您的应用程序处理多播时,操作系统会发送和接收 IGMP 消息。这是自动的,依赖于对 IP_ADD_MEMBERSHIP 等的正确调用,但除此之外,您无法控制它。中间的硬件组件(WLAN 路由器、交换机、电力线适配器……)都可以使多播工作变魔术,而这种魔术往往会隐藏问题并制造问题。

一个例子:如果您的进程为多播地址 X 调用 IP_ADD_MEMBERHIP,那么机器上的所有其他进程也将看到来自地址 X 的多播流量,即使它们未能调用 IP_ADD_MEMBERSHIP。

丢失(或伪造)ADD_MEMBERSHIP 的典型症状是:它工作几分钟(通常为 3 到 5 分钟),然后突然停止工作,就好像电缆被拉了一样。在接下来的 3-5 分钟内,重新启动其中一个程序会再次解决问题。但即使使用 100% 正确的 ADD_MEMBERSHIP,您在穿越电力线适配器等重要网络组件时也会出现此类症状。那么这是您正在使用的操作系统与您正在使用的路由器/交换机/适配器之间的某种不兼容。

要对此进行调试,请尝试检查主机操作系统的 IGMP 状态。我不知道如何在 Windows 上执行此操作。

于 2015-10-21T22:34:32.100 回答