UDP套接字(多播)未接收数据(Ubuntu)

3

我正在尝试在Linux(Ubuntu)上基于我写过的Winsock代码建立一个小型测试应用程序。目前,它只是一个创建套接字的小型测试,看起来成功连接,但却在recv()上永久挂起,而无法接收数据报。它是一个纯阻塞套接字。

以下是我创建它的方式:

http://pastebin.com/kcCbgxbB

一些进一步的测试: - 端口是开放的。 - 其他应用程序能够成功地从多播地址接收数据。
显然我忽视了某些东西。非常感谢您的帮助 :-)

1
你没有检查所有调用 setsockopt() 的结果,看看它们是否成功。也许其中一个失败了,这与你的问题有关? - Jeremy Friesner
好的观点,我更多或少是把他们的成功视为理所当然 :) 然而,添加的检查显示他们也成功了。 - nielsj
1
我尝试了一下,它运行得很好。 - GabiMe
谢谢你。这再次证实了我的信念,这是一个配置问题。 - nielsj
由于某些原因,在这里使用Mac和Ubuntu时它不起作用,但是当我绑定到INADDR_ANY而不是绑定到特定接口时,在两者上都可以工作。 - epx
2个回答

5

在Unix系统中,当使用套接字进行多播时,应该绑定到INADDR_ANY,而不是一个接口。

通过接口进行多播过滤(即仅从指定接口接收mcast)已经就位,因为您正确地填充了imr_interface。


1
我不会准确地称其为“过滤”。imr_interface 选择通过哪个接口发送 IGMP JOIN,换句话说,哪个子网知道您的成员身份。如果您让它默认,那么您就让静态 IP 路由表决定,这在大多数情况下是正确的。在多主机中,可能需要针对每个接口发出加入请求。 - user207421
1
在所有情况下,最终的软件将在多宿主系统上使用。话虽如此,在Winsock中INADDR_ANY确实可以正常工作。然而,当将套接字绑定到ANY并将接口绑定到特定NIC的IP时,组加入总是失败的。--但是,是的,我现在会回到INADDR_ANY。 - nielsj

4

最后,在进行一些系统配置和故障修复后,问题得到了解决:

a) 以root身份,需要执行以下操作来禁用反向数据包过滤器: echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter + 对于ethX同样适用。

b) 为ethX添加虚假路由(route add -net 224.0.0.0. netmask 224.0.0.0 ethX)

c) 将socket绑定到要加入组的IP地址(否则任何后续的socket都会在该特定端口上接收来自所有已经加入的组的数据包)。

d) 将ip_mreq结构体的接口成员设置为我们正在接收的适配器的IP地址。

然后一切正常,测试运行快速、顺畅(以800-900兆比特的速度拉取125个组播传输流 - 当然这可以更智能,但仍然很好)。感谢提供的所有指导。


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