David Levy
David Levy

Reputation: 511

Reading from UDP socket over WiFi always timeout

I have a piece of code that send a UDP broadcast to scan for device on our local network. It works fine when im plugged via ethernet, but it doesnt when im connected via WiFi.

Is there something different to do to connect in UDP when using WiFi?

You can find the code im using below. When using WiFi, select always return 0

struct sockaddr_in addr;

//Create socket
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
    perror("socket");
    exit(1);
}

/* set up destination address */
memset((char *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(48620);
addr.sin_addr.s_addr = inet_addr("192.168.3.255");

//TRYING TO BIND, NOT WORKING
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
    int a = WSAGetLastError(); //ERROR 10049
    perror("bind"); //Says NO ERROR
  }


//allow broadcast
int broadcast = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)) == -1)
    exit(1);


    if (sendto(fd, (const char *)&request, sizeof(request), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
    {
        perror("sendto");
        exit(1);
    }

    do
    {
        FD_ZERO(&rdFs);
        FD_SET(fd, &rdFs);
        lTimeout.tv_sec = 1;
        lTimeout.tv_usec = 000000;
        lSelRet = select(fd, (fd_set*)&rdFs, NULL, NULL, &lTimeout);
        if (lSelRet > 0 && FD_ISSET(fd, &rdFs))
        {
            addrFromSize = sizeof(addrFrom);
            lResult = recvfrom(fd, bufferIn, sizeof(bufferIn), 0, (struct sockaddr *) &addrFrom, &addrFromSize);
            //Treat result
        }
    } while (lSelRet > 0);

Note : Even using WiFi, i can estalbish a TCP connection and communicate with the device, its just the UDP broadcast that doesnt work

Note2: currently testing on windows, but I will port it to Linux after

Edit : added the SO_BROADCAST as advised by Remy

Upvotes: 0

Views: 1736

Answers (1)

David Levy
David Levy

Reputation: 511

Finally got it working, it was a code issue, not a router issue.

The issue was a misuse of the bind function, I needed to use my IP and not the broadcast IP.

/* set up destination address */
memset((char *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(48620);
addr.sin_addr.s_addr = inet_addr("192.168.3.134");   //<== Windows : My IP, not the broadcast IP
addr.sin_addr.s_addr = INADDR_ANY; //Linux

if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
    perror("bind");
}

EDIT : strangely enough, in windows you must bind to the ip sending the request, and on linux you must bind to INADDR_ANY.

Upvotes: 1

Related Questions