2017-07-19 146 views
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)傳遞,或者正如?

+0

當然,您應該總是使用'htons()'來解決可移植性問題,該函數將根據運行代碼的機器執行所需的轉換。但是如果你在X86架構上使用它,你必須使用'htons()'**,因爲網絡字節順序幾乎總是big_endian。 –

+0

@Frankie_C,在這種情況下,我應該在指定sin_addr時使用'htonl'嗎?無論哪種方式,我仍然無法接收UDP廣播數據包。 – weblar83

+0

看看這裏:https://stackoverflow.com/questions/41022253/udp-winsock-not-receiving-broadcast-packets,http://www.binarytides.com/udp-socket-programming-in-winsock/ –

回答

0

好了,問題是這一行的代碼,特別是最後兩個參數:

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

length從未被初始化(應該是sizeof(sockaddr_in))和&socket應該是一個不同的sockaddr_in結構 - 而不是一個在bind調用中使用。

對不起大家,忽略了!