IPC Broadcast messages....won't work off the net.

roberts136 - September 2, 2010

I've implemented some IPC code to deliver broadcast messages between processes based on sockets. One sender, many listeners listening to a common port. Standard socket code (i think), the sender sending on INADDR_BROADCAST , port 49999, the listener listening on INADDR_ANY, port 49999.  It all works very well just how I want it too.......almost. 

When I run the code on a machine connected to the network, which gets its network configuration via DHCP, (or statically configured) this IPC broadcast mechanism works fine. If I run the same code on a machine that was booted while off the network the code doesn't work. The receivers never receive the messages. It seems at least one interface must be configured at boot time...or it won't work.

I know, not much to go on..... any ideas? Code below

 

int CIpc::ipcSend_Message(char* message, int msgSize, int port, int broadcast){

int bytes_sent;
int osock; //the socket for sending information
struct sockaddr_in osa; //the socket address for sending information
osock = socket(AF_INET, SOCK_DGRAM, 0);
if (osock < 0) {/* if socket failed dest initialize, exit */
perror("Socket");
return -1;
}
if(broadcast)
{
int on =1;
setsockopt(osock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
}
memset(&osa, 0, sizeof(osa));
osa.sin_family = AF_INET;
if(broadcast)
osa.sin_addr.s_addr = htonl(INADDR_BROADCAST);//Broadcast
else
osa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);//local host
osa.sin_port = htons(port);
bytes_sent = sendto(osock, message, msgSize, 0,(struct sockaddr*)&osa, sizeof (struct sockaddr_in));
close(osock);
if(bytes_sent < 0)
return -1;
return 0;
}
int CIpc::ipcGet_Message(char* buffer, int buffer_size, int block){
socklen_t addrLen;
fd_set ready; //The ready flag for a message waiting in one of the ports
int rec;
if(sock < 0)
return(-1);
addrLen = sizeof(struct sockaddr_in);
FD_ZERO(&ready);
FD_SET(sock, &ready);
if(block == IPC_BLOCK)
{
rec = select(sock+1, &ready, NULL, NULL, NULL);
}
else
rec = select(sock+1, &ready, NULL, NULL, &waitd);
if(rec>0){
if(FD_ISSET(sock, &ready)){
FD_CLR(sock, &ready);
recsize = recvfrom(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)&sa, &addrLen);
}
if (recsize < 0){
printf("%d\n", errno);
perror("recvfrom");
return(-1);
}
return recsize;
}
return 0;
}
int CIpc::ipcStart_Listening(int port, int broadcast){
if(sock > 0)
{
close(sock);
return(-1);
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {/* if socket failed dest initialize, exit */
perror("socket");
return -1;
}
if(broadcast)
{
int on =1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
}
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(port);
if (-1 == bind(sock,(struct sockaddr *)&sa, sizeof(struct sockaddr)))
{
perror("bind");
close(sock);
return -1;
}
int x = fcntl(sock, F_GETFL, NULL);
fcntl(sock,F_SETFL,x|O_NONBLOCK);
return 0;
}

Share this

Comments

Do you see outgoing packets

Do you see outgoing packets with utility such as tcpdump?  If you can supply a sender/receiver pair that I can compile, I can try try locally.

Steve