从wifi始终超时从UDP插座读取

Reading from UDP socket over WiFi always timeout

本文关键字:插座 读取 UDP wifi 超时      更新时间:2023-10-16

我有一个代码,该代码将UDP广播发送以扫描我们本地网络上的设备。当im通过以太网插入时,它可以正常工作,但是当我通过wifi连接时,它不会。

使用wifi时,在UDP中连接有不同的操作吗?

您可以使用下面找到IM的代码。使用WiFi时,select始终返回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);

注意:即使使用wifi,我也可以与TCP连接并与设备进行通信,它只是无法正常工作的UDP广播

Note2:当前在Windows上进行测试,但是我将其移植到Linux之后

之后

编辑:按照雷米建议添加so_broadcast

最终使它起作用,这是一个代码问题,而不是路由器问题。

问题是滥用绑定功能,我需要使用我的IP,而不是广播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");
}

编辑:奇怪的是,在Windows中,您必须绑定到IP发送请求,在Linux上,您必须绑定到Inaddr_any。