I'll do my best to keep it short.
Question is: What could be the cause of being unable to receive multicast packets on non virtualised code (Non JVM)
OS:
Rust code: (Does not work)
use std::net::UdpSocket;
fn main() {
let udp = UdpSocket::bind("[::]:0").expect("Unable to bind!");
println!("{}", udp.local_addr().unwrap());
udp.connect("ff02::fb%en0:5353").unwrap();
let mut buffer = [0; 65000];
let size = udp.recv(&mut buffer).unwrap();
println!("Data received: {}", size);
}
Kotlin (JVM) code: Works
import java.net.DatagramPacket
import java.net.MulticastSocket
fun main() {
val port = 5353 // Multicast port
val socket = MulticastSocket(port)
val buffer = ByteArray(1024)
val packet = DatagramPacket(buffer, buffer.size)
println("UDP server listening for multicast packets on ${socket.localSocketAddress}")
while (true) {
socket.receive(packet)
val receivedData = packet.data.copyOf(packet.length)
val receivedMessage = String(receivedData)
println("Received message: $receivedMessage")
}
}
C code: (Does not work)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_LEN 1024 // Maximum message length
int main() {
int sockfd;
struct sockaddr_in addr;
struct ip_mreq mreq;
char buffer[MAX_LEN + 1];
int bytes_received;
// Create a UDP socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(addr));
// Fill in the address structure
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY); // Listen on any interface
addr.sin_port = htons(12345); // Choose any port number you like
// Bind the socket to the address
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Specify the multicast group to join
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.251"); // Multicast group address
mreq.imr_interface.s_addr = htonl(INADDR_ANY); // Listen on any interface
// Join the multicast group
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// Receive multicast messages
while (1) {
bytes_received = recvfrom(sockfd, buffer, MAX_LEN, 0, NULL, NULL);
if (bytes_received < 0) {
perror("recvfrom failed");
exit(EXIT_FAILURE);
}
buffer[bytes_received] = '\0'; // Null-terminate the received data
printf("Received message: %s\n", buffer);
}
// Close the socket
close(sockfd);
return 0;
}
I answered on a similar question (also posted by me trying to clarify things more): mDNS / Bonjour / UDP 5353 Port reusability