简体   繁体   中英

Not receiving multicast data using code which works on another machine

We receive multicast data to two machines- Prod and Dev. The below code worked on Prod, but has never worked on Dev (even though the boxes should be set up identically). However, when I run

tshark -i <interface> -c 50

on Dev packets are being received from the same multicast address and port as Prod.

I have posted the code below. The program reaches the log line "Listening for packets" but then appears to simply block on recvfrom() .

I would like to clarify I am not doing anything daft. Is there anything else I can check to see what's happening with the packets? I cannot speak with our vendor yet because they will simply run tshark and say the problem must be with our code.

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);
}

You're specifying INADDR_ANY as the interface to join the multicast group on. This means the system will choose a default interface. If your system has more than one active interface, it might not be the one you intended.

What's probably happening here is that your PROD machine happens to be joining on the desired interface, while the DEV machine is joining on a different interface.

Change mreq.imr_interface to contain the IP address of the network interface you want to bind to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM