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 switch between the transmitter and receiver, it drops most packets.
I realize that multicast isn’t guaranteed, however, this 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.
Finally, I should mention that I can send the UDP packets from the TX1 to another computer just fine, I get all the packets. When I switch the configuration and try to received on the TX1, my packets are dropped. (Most of them are dropped).
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));