如果我跑:
iperf -s -u -B 224.0.31.155
并运行
sudo tcpdump -ni any 'host 224.0.31.155'
tcpdump能够捕获一些内容:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
15:49:15.334484 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 1364
15:49:15.334728 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 1374
15:49:15.375026 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 1058
15:49:15.375184 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 832
但是,如果我杀死上面的iperf进程,然后启动我的C ++应用程序,该应用程序也加入同一个组并绑定同一个端口,tcpdump将不再看到流量。
以下是摘录:
struct sockaddr_in mc_addr; /* socket address structure */
struct ip_mreq mc_req; /* multicast request structure */
unsigned int from_len = sizeof(mc_addr); /* source addr length */
/* construct a multicast address structure */
memset(&mc_addr, 0, from_len);
mc_addr.sin_family = AF_INET;
inet_aton(mcastGroup.c_str(), &mc_addr.sin_addr);
mc_addr.sin_port = htons(port);
/* bind to multicast address to socket */
if (bind(s, (struct sockaddr *) &mc_addr, sizeof(mc_addr)) < 0) {
std::cerr << "failed to bind to the port " << port << "|error="
<< strerror(errno) << std::endl;
throw;
}
/* construct an IGMP join request structure */
mc_req.imr_multiaddr.s_addr = inet_addr(mcastGroup.c_str());
mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
/* send an ADD MEMBERSHIP message via setsockopt */
if ((setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &mc_req,
sizeof(mc_req))) < 0) {
std::cerr << "failed to set socket option to request for membership"
<< std::endl;
throw;
}
tcpdump详细信息:
$ tcpdump --version
tcpdump version 4.1-PRE-CVS_2012_03_26
libpcap version 1.4.0
我刚刚在我的一台生产服务器上检查了它,它显示了相同的行为,但我看到我的C ++应用程序正在正确处理数据。
知道发生了什么事吗?
答案 0 :(得分:0)
代码中的一个潜在问题是您将套接字绑定到多播地址。这不是必需的,可能会导致各种奇怪的行为。
如果您只想发送 UDP数据包,则根本不需要绑定套接字。操作系统会为您完成。
如果要发送和接收多播流量,则最有可能希望绑定到Linux上的INADDR_ANY。这几乎是一个习语。 UDP套接字上的bind()
在Linux上具有非常不直观的语义。 IP地址只具有过滤功能。它既不绑定到指定的IP地址,也不绑定到与该IP地址关联的接口。
另一个奇怪的事情是你分配给mc_req.imr_interface
,ip_mreq
不应该是mc_req.imr_address
的成员。我认为这应该是.site-main ul.products li.product .g-product-title {opacity:1!important; }
,但当然如果编译,我会保持沉默。
答案 1 :(得分:0)
IGMP消息是守恒的。如果主机已经是该组的成员,则当另一个应用程序加入时,它不会发送新的IGMP成员身份报告消息。如果您正在接收多播,请高兴。