不使用在另一台机器上工作的代码接收多播数据
Not receiving multicast data using code which works on another machine
我们将多播数据接收到两台机器 - Prod 和 Dev。下面的代码在 Prod 上工作,但从未在 Dev 上工作(即使盒子应该设置相同)。然而,当我 运行
tshark -i <interface> -c 50
正在从与 Prod 相同的多播地址和端口接收 Dev 数据包。
我已经发布了下面的代码。该程序到达日志行 "Listening for packets" 但随后似乎只是在 recvfrom()
.
上阻塞
我想澄清一下,我没有做任何愚蠢的事情。还有什么我可以检查数据包发生了什么事吗? 我还不能和我们的供应商交谈,因为他们只会 运行 tshark 并说问题一定出在我们的代码上。
std::string address("1.2.3.4"); // Not real address
const char *group = address.c_str();
int port = 26477;
_sock = socket(AF_INET, SOCK_DGRAM, 0);
assert(_sock >= 0);
u_int yes = 1;
int result = setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
assert(result >= 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
result = bind(_sock, (struct sockaddr *)&addr, sizeof(addr));
assert(result >= 0);
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
result = setsockopt(_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
assert(result >= 0);
LOG("Listening for packets...."); // CODE REACHES HERE
while (1)
{
socklen_t addrlen = sizeof(addr);
const size_t maxNumBytesToRead = MSGBUFSIZE - 1;
// I think code is just blocking here, waiting for packets
const int nbytes = recvfrom(_sock, msgbuf, maxNumBytesToRead, 0, (struct sockaddr *)&addr, &addrlen);
}
您正在指定 INADDR_ANY
作为加入多播组的接口。这意味着系统将选择一个默认界面。如果您的系统有多个活动界面,它可能不是您想要的界面。
这里可能发生的情况是,您的 PROD 机器恰好在所需的接口上加入,而 DEV 机器在不同的接口上加入。
更改 mreq.imr_interface
以包含您要绑定到的网络接口的 IP 地址。
我们将多播数据接收到两台机器 - Prod 和 Dev。下面的代码在 Prod 上工作,但从未在 Dev 上工作(即使盒子应该设置相同)。然而,当我 运行
tshark -i <interface> -c 50
正在从与 Prod 相同的多播地址和端口接收 Dev 数据包。
我已经发布了下面的代码。该程序到达日志行 "Listening for packets" 但随后似乎只是在 recvfrom()
.
我想澄清一下,我没有做任何愚蠢的事情。还有什么我可以检查数据包发生了什么事吗? 我还不能和我们的供应商交谈,因为他们只会 运行 tshark 并说问题一定出在我们的代码上。
std::string address("1.2.3.4"); // Not real address
const char *group = address.c_str();
int port = 26477;
_sock = socket(AF_INET, SOCK_DGRAM, 0);
assert(_sock >= 0);
u_int yes = 1;
int result = setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
assert(result >= 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
result = bind(_sock, (struct sockaddr *)&addr, sizeof(addr));
assert(result >= 0);
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
result = setsockopt(_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
assert(result >= 0);
LOG("Listening for packets...."); // CODE REACHES HERE
while (1)
{
socklen_t addrlen = sizeof(addr);
const size_t maxNumBytesToRead = MSGBUFSIZE - 1;
// I think code is just blocking here, waiting for packets
const int nbytes = recvfrom(_sock, msgbuf, maxNumBytesToRead, 0, (struct sockaddr *)&addr, &addrlen);
}
您正在指定 INADDR_ANY
作为加入多播组的接口。这意味着系统将选择一个默认界面。如果您的系统有多个活动界面,它可能不是您想要的界面。
这里可能发生的情况是,您的 PROD 机器恰好在所需的接口上加入,而 DEV 机器在不同的接口上加入。
更改 mreq.imr_interface
以包含您要绑定到的网络接口的 IP 地址。