0
我有一個通過UDP廣播地址發送數據包的設備。WinSock - 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)
傳遞,或者正如?
當然,您應該總是使用'htons()'來解決可移植性問題,該函數將根據運行代碼的機器執行所需的轉換。但是如果你在X86架構上使用它,你必須使用'htons()'**,因爲網絡字節順序幾乎總是big_endian。 –
@Frankie_C,在這種情況下,我應該在指定sin_addr時使用'htonl'嗎?無論哪種方式,我仍然無法接收UDP廣播數據包。 – weblar83
看看這裏:https://stackoverflow.com/questions/41022253/udp-winsock-not-receiving-broadcast-packets,http://www.binarytides.com/udp-socket-programming-in-winsock/ –