I have a network application meant for a private LAN. I am doing my testing using loopback. When I test on the LAN the socket creation order does not matter. If I test using loop back 127.0.0.1 then there is a socket creation ordering issue. Why is it different on loop back?
Here are more details...
There is one server, and many client instances. The server is broad casting data over UDP. The clients receive the data and process it.
I need to have the network layer not care about the order in which either the server or clients start. It is hard to administer process creation for my case. The application instances should be able to start on the network in any order and just see the data broadcasted on the UDP port when it is sent.
But there is something in the way I setting up my UDP sockets which is forcing ordering to take place. I must start the clients, THEN start the server. If I start the clients AFTER the server doing the UDP broadcast, the client sockets do not receive the data. If I force a running server instance to tear down and rebuild its UDP socket, suddenly all the clients start receiving data.
There must be something wrong with how I creating the socket. The client and server code use a shared function library to make the UDP socket. So the server is sending on m_fdOut. Each instance of the client is receiving on m_fdIn.
What am I doing wrong here?
SOCKET m_fdIn;
SOCKET m_fdOut;
if ((m_fdIn = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
WARNF("socket failed, winsock error %d\n", WSAGetLastError());
exit(1);
}
if ((m_fdOut = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
WARNF("socket failed, winsock error %d\n", WSAGetLastError());
exit(1);
}
int sockopt = 1;
if (setsockopt(m_fdOut, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt,
sizeof(sockopt)) < 0)
{
WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
exit(1);
}
sockopt = readPreference<int>("SOL_RCVBUF", 512*1024);
if (setsockopt(m_fdIn, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt)) < 0)
{
WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
exit(1);
}
sockopt = 1;
if (setsockopt(m_fdIn, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)) < 0)
{
WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
exit(1);
}
sockopt = readPreference<int>("IP_MULTICAST_TTL", 32);
if (setsockopt(m_fdOut, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&sockopt, sizeof(sockopt)) < 0)
{
WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
exit(1);
}
String destAdd = "255.255.255.255"
int portNumber = 1234;
int n1, n2, n3 ,n4;
if (sscanf(destAddr, "%d.%d.%d.%d", &n1, &n2, &n3, &n4) != 4)
{
n1 = n2 = n3 = n4 = 255;
}
u_long bcastAddr = (n1<<24) | (n2<<16) | (n3<<8) | n4;
outAddr.sin_family = AF_INET;
outAddr.sin_port = htons(portNumber);
outAddr.sin_addr.s_addr = htonl(bcastAddr);
struct sockaddr_in in_name;
in_name.sin_family = AF_INET;
in_name.sin_addr.s_addr = INADDR_ANY;
in_name.sin_port = htons(portNumber);
if (bind(m_fdIn, (struct sockaddr *)&in_name, sizeof(in_name)) < 0)
{
WARNF("bind failed, winsock error %d\n", WSAGetLastError());
exit(1);
}