I have an application that receives multicast packets. If I direct connect the receiver to the transmitter, it receives everything fine. If I add a router between the transmitter and receiver, it drops most packets.
I realize that multicast isn't guaranteed, however, it is behaving strange. The transmitter send ~250 multicast packets that are 1490 bytes in a burst that takes about 4 microseconds, 10 times every second. I receive the first ~80 packets, drop the other ~170 each time.
I also tested my code on openSUSE and connected to the same router and it worked fine. Then I tested with Windows and it worked fine. So, I am starting to think my Ubuntu is misconfigured. Especially given the low data rate.
Any help would be appreciated.
If it helps, the following is the code used to create the multicast socket and receive (on Windows I used boost):
// Create the socket
int socket = socket(AF_INET, SOCK_DGRAM, 0);
if (!socket) throw std::runtime_error(strerror(errno));
int reuse = 1;
if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
{
throw std::runtime_error(strerror(errno));
}
struct sockaddr_in endpoint;
memset(&endpoint, 0, sizeof(endpoint));
local.sin_family = AF_INET;
local.sin_port = htons(port);
local.sin_addr.s_addr = INADDR_ANY;
if (bind(socket, (struct sockaddr*)&endpoint, sizeof(endpoint)) < 0)
{
throw std::runtime_error(strerror(errno));
}
struct ip_mreq group;
group.imr_multiaddr.s_addr = inet_addr(ip.c_str());
group.imr_interface.s_addr = INADDR_ANY;
if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&group, sizeof(group)) < 0)
{
throw std::runtime_error(strerror(errno));
}
int recvBufferSize = 8 * 1024 * 1024;
if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (const char*)&recvBufferSize, sizeof(recvBufferSize)) < 0)
{
throw std::runtime_error(strerror(errno));
}
// receive data
socklen_t addrLen = sizeof(endpoint);
const ssize_t rc = recvfrom(socket, msg, size, 0, (struct sockaddr*)endpoint, &addrLen);
if (rc < 0) throw std::runtime_error(strerror(errno));