Reputation: 731
I have a device which sends out data packets via the UDP broadcast address.
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.
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:
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.
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. 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?
Upvotes: 2
Views: 3089
Reputation: 731
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.
Sorry guys, overlooked that!
Upvotes: 1