代码之家  ›  专栏  ›  技术社区  ›  Fred

无法接收UDP广播消息

  •  0
  • Fred  · 技术社区  · 7 年前

    我正在尝试组装一个UDP监视器。我原以为这是直截了当的,但我所尝试的一切都失败了。

    code example . 由于我过去的尝试失败,我只是复制了网站的代码并更改了端口号(见下文),但我仍然无法接收数据报。

    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>
    
    int iResult = 0;
    WSADATA wsaData;
    SOCKET RecvSocket;
    sockaddr_in RecvAddr;
    unsigned short Port = 18190;
    
    char RecvBuf[1024];
    int BufLen = 1024;
    sockaddr_in SenderAddr;
    int SenderAddrSize = sizeof (SenderAddr);
    
    //-----------------------------------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error %d\n", iResult);
        return 1;
    }
    //-----------------------------------------------
    // Create a receiver socket to receive datagrams
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (RecvSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Bind the socket to any address and the specified port.
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(Port);
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    iResult = bind(RecvSocket, (SOCKADDR *) &RecvAddr, sizeof (RecvAddr));
    if (iResult != 0) {
        wprintf(L"bind failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Call the recvfrom function to receive datagrams
    // on the bound socket.
    wprintf(L"Receiving datagrams...\n");
    iResult = recvfrom(RecvSocket,
                       RecvBuf, BufLen, 0, (SOCKADDR *) &SenderAddr, &SenderAddrSize);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
    }
    
    //-----------------------------------------------
    // Close the socket when finished receiving datagrams
    wprintf(L"Finished receiving. Closing socket.\n");
    iResult = closesocket(RecvSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
        return 1;
    }
    
    //-----------------------------------------------
    // Clean up and exit.
    wprintf(L"Exiting.\n");
    WSACleanup();
    

    使用Wireshark,我看到消息如预期般传入(源IP地址为10.1.1.150) Wireshark capture

    我在Windows 10防火墙中添加了一些规则,以确保端口18190处于打开状态,并且不会拒绝在该端口上传入或传出的消息。

    许多网站声明,对于客户端,你不应该绑定套接字,但是如果我不绑定套接字,那么 recvfrom() WSAEINVAL ,表示提供了无效的参数。

    注意:我想使用 而不是 recv() ,因为我需要发件人地址信息。

    我试着通过电子邮件发送消息 sendto() 打电话之前 recvfrom() 仍然没有得到任何东西(即,它只是永远阻塞)。

    更新2

    使用上述代码,如果我将计算机的静态IP地址设置为10.1.1.255,那么我就能够接收数据包。这告诉我代码可以接收数据包,但仍然不能解释为什么我不能接收广播数据包。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Fred    7 年前

    所以我终于发现了问题,它是愚蠢的。我在这里发布解决方案,也许是为了帮助其他人。

    我的子网掩码默认为255.0.0.0,这对于获取广播数据包是不正确的。将子网掩码更改为255.255.255.0允许代码获取广播数据包。

    推荐文章