I am trying to implement some discovery mechanism for a network device. The goal is for my application to discover a device on the network independent of the network configuration (IPv4).
My device is waiting for a UDP broadcast (255.255.255.255) on a fixed port and with fixed content. If the content matches, the device sends a broadcast (again to 255.255.255.255), which should be received by the PC.
Now my issue is on the PC side: The PC should send a broadcast on a specific network interface. For that, I bind the socket to a network address. On Windows this solution would work perfectly. But on Linux it seems to be more difficult. When I bind the socket to a network address, I couldn't receive any broadcast on it.
int ret;
this->port = port;
socketfd = socket(AF_INET, SOCK_DGRAM, 0);
if (socketfd < 0) {
this->port = 0;
return;
}
struct sockaddr_in bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr));
bindAddr.sin_family = AF_INET;
bindAddr.sin_addr.s_addr = inet_addr("192.168.2.104");//ipV4;
bindAddr.sin_port = htons(port);
ret = bind(socketfd, (struct sockaddr *)&bindAddr, sizeof(bindAddr));
if (ret < 0) {
int error = errno;
this->port = 0;
return;
}
int broadcastOpt = 1;
ret = setsockopt(socketfd, SOL_SOCKET, SO_BROADCAST, &broadcastOpt, sizeof(broadcastOpt));
if (ret < 0) {
//int error = errno;
this->port = 0;
return;
}
I also found the sockopt SO_BINDTODEVICE
, which is fine when I execute the application as root. But in the end this is not a solution for my application.
Does anyone have an idea on how to bind the UDP Broadcast to a single network interface while also being able to receive any broadcasts on this interface?