无法接收UDP广播消息

时间:2018-12-11 21:11:19

标签: c++ sockets udp recvfrom

我正在尝试组装一个UDP监视器。我以为这很简单,但是我尝试过的所有方法都无法正常工作。

当前,我正在使用Microsoft 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()会立即返回-1和错误WSAEINVAL,该错误指出, “提供了无效的参数。”

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

有人可以帮助我理解为什么此代码未收到广播的UDP数据报吗?

更新

我在致电sendto()之前尝试通过recvfrom()发送消息。 Wireshark显示消息已发送至10.1.1.150,但recvfrom()仍然没有收到任何消息(即,它将永远被阻止)。

更新2

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

1 个答案:

答案 0 :(得分:0)

所以我终于找到了问题,这很愚蠢。我将解决方案发布在这里,也许可以帮助其他人。

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