C语言 WinSock - UDP 广播侦听器



我有一个通过UDP广播地址发送数据包的设备。

我正在尝试将一个 winsock 应用程序放在一起来侦听这些广播消息,但最终,我在设置 UDP 套接字方面没有取得多大成功。

这是我必须创建套接字并启动侦听器线程的代码:

DWORD CreateStatusListener() {
WORD wVersion;
WSADATA wsa;
int err;
wVersion = MAKEWORD(2, 2);
err = WSAStartup(wVersion, &wsa);
if (err != 0) {
// Fail gracefully
// ...
}
// Create the UDP status socket
m_iSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (m_iSocket == SOCKET_ERROR) {
// Fail gracefully
// ...
}
m_bAbort = FALSE;
// Create the UDP status socket listener thread
m_hThread = CreateThread(NULL, 0, PollStatusSocket, NULL, 0, &m_dwThreadID);
if (!m_hThread) {
// Fail gracefully
// ...
}
return ERR_SUCCESS;
}

此函数成功,设置套接字并创建线程。

我的 UDP 轮询函数如下:

static DWORD WINAPI PollStatusSocket(LPVOID lpParam) {
struct sockaddr_in socket;
INT length;
// Set up the address struct
memset(&socket, 0, sizeof(socket));
socket.sin_family = AF_INET;
socket.sin_port = htons(52102);
socket.sin_addr.s_addr = INADDR_BROADCAST;
INT err = SOCKET_ERROR;
INT bAllow = 1;
err = setsockopt(m_iSocket, SOL_SOCKET, SO_BROADCAST, (char *)&bAllow, sizeof(bAllow));
// Allocate a receive buffer
char ucBuffer[BUFFER_LEN];
// Loop while the thread is not aborting
while (!m_bAbort) {
err = recvfrom(m_iSocket, ucBuffer, BUFFER_LEN, 0, (SOCKADDR *)&socket, &length);
if (err != SOCKET_ERROR) {
// Check we have a valid status message
// ...
}
else {
err = WSAGetLastError();
printf("Error: %d", err);
}
}
return 0;
}

轮询线程期间发生的情况是recvfrom返回 -1,WSAGetLastError报告WSAEINVAL错误 - 无效参数。

我见过的一些代码示例使用bind方法,但据我所知,我不需要在广播地址上调用bind。我考虑的一件事是是否正确分配了sockaddr_in结构 - 例如,端口号是否需要按htons(port)传递或仅按原样传递?

好的,所以问题出在这一行代码上,特别是最后两个参数:

err = recvfrom(m_iSocket, ucBuffer, BUFFER_LEN, 0, (struct sockaddr *)&socket, &length);

length从未被初始化(应该被sizeof(sockaddr_in)(,&socket应该是不同的sockaddr_in结构 - 而不是bind调用期间使用的结构。

对不起,伙计们,忽略了这一点!