[英]WinSock - UDP Broadcast Listener
I have a device which sends out data packets via the UDP broadcast address. 我有一台通过UDP广播地址发送数据包的设备。
I'm attempting to put together a winsock application to listen for these broadcast messages but ultimately, I'm not having much success setting up a UDP socket. 我试图将Winsock应用程序放在一起以侦听这些广播消息,但最终,设置UDP套接字并没有取得太大的成功。
Here's he code I have to create the socket and start the listener thread: 这是我必须创建套接字并启动侦听器线程的代码:
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;
}
This function succeeds, with the socket being set up and the thread being created. 该函数成功完成,并建立了套接字并创建了线程。
My UDP polling function is as follows: 我的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;
}
What happens during the polling thread is that recvfrom
returns -1 and the WSAGetLastError
reports a WSAEINVAL
error - invalid argument. 轮询线程期间发生的情况是
recvfrom
返回-1,并且WSAGetLastError
报告WSAEINVAL
错误-无效参数。
Some code examples I've seen use the bind
method but as far as I was aware, I don't need to call bind
on a broadcast address. 我已经看到一些代码示例使用
bind
方法,但是据我所知,我不需要在广播地址上调用bind
。 One thing I have considered is whether the sockaddr_in
struct was assigned correctly - for example, does the port number need to be passed as htons(port)
or just as is? 我考虑过的一件事是,是否正确分配了
sockaddr_in
结构-例如,是否需要将端口号作为htons(port)
或原样传递?
Ok, so the issue was with this line of code, specifically the last two parameters: 好的,问题出在这行代码,特别是最后两个参数:
err = recvfrom(m_iSocket, ucBuffer, BUFFER_LEN, 0, (struct sockaddr *)&socket, &length);
length
was never being initialized (should be sizeof(sockaddr_in)
) and &socket
should be a different sockaddr_in
struct - not the one used during the bind
call. 从未初始化过
length
(应该为sizeof(sockaddr_in)
),并且&socket
应该是不同的sockaddr_in
结构-而不是在bind
调用期间使用的结构。
Sorry guys, overlooked that! 抱歉,大家忽略了!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.