1
votes

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);
}
1
I won't read the entire code here, but instead ask a concept question: The server sends periodically to the broadcast, yes? Or just once as 'Hello, here I am'?Refugnic Eternium
The server is sending out a series of datagrams over broads cast. The data is such that it is ok for any client instance to pick up 'in the middle' of the data stream and start doing its thing.meissnersd
Broadcasting to 255.255.255.255 has been deprecated for about 20 years. You should use a subnet-directed broadcast. You also don't need two UDP sockets in the same process: one will do.user207421
Usually we subnet. I was sending 255 for testing. There is SOME data that flows from the clients back to the server. I tried a single socket implementation. The server was receiving the data it sent. There was not an obvious way to filter it out since the sender address is mine but I explicitly need to handle loopback.meissnersd

1 Answers

0
votes

So I did change the implementation from UDP broadcast to multicast. That seems to work in loopback so multiple processes can share the port.