我正在編寫一個簡單的客戶端 - 服務器應用程序,它暫時將用於我自己的個人使用。我正在使用Winsock進行網絡通信。過去10年我沒有建立任何網絡,所以我很生疏。我想盡可能使用盡可能少的外部代碼,所以我寫了一個自制的服務器發現機制,如下所示。UDP上的recv()失敗
客戶端廣播包含綁定到任意端口的客戶端UDP套接字的「名稱」的消息,我將其稱爲客戶端的發現套接字。服務器recv()廣播,然後sendto()客戶端發現套接字的偵聽套接字的'名稱'。客戶端然後使用此信息連接到服務器(在不同的套接字上)。這種機制應該允許服務器將其監聽套接字綁定到它可以在動態端口範圍(49152-65535)內的第一個端口,並且允許客戶端發現服務器在哪裏以及它正在監聽的端口。
服務器部分正常工作:服務器接收廣播消息併成功發送其響應。
在客戶端,防火牆日誌顯示服務器的響應到達機器,並且它被髮送到正確的端口(到客戶端的發現套接字)。 但是這條消息從來沒有讓它到客戶端應用程序。我試過在阻塞和非阻塞模式下做recv(),並且從來沒有任何可用的數據。 ioctlsocket()始終顯示沒有數據可用,即使我知道數據包已將其發送到機器。
服務器成功對廣播數據執行recv()。但是,客戶端無法執行發送套接字的服務器響應的recv()。
這個問題非常模糊:在這種情況下應該注意什麼問題?爲什麼recv()無法獲得實際到達機器的數據包?套接字是UDP,所以它們沒有連接的事實是不相關的。或者是?
非常感謝提前。
謝謝EJP,我不知道recvfrom()不需要知道遠程地址;我會用它。 – user1752563 2013-02-22 16:10:41
@ user1752563我沒有說recvfrom()不需要知道遠程地址。我說你可以通過使用recvfrom()獲得遠程地址,所以你不必把它放在有效載荷中。其實我可能會想到recvmsg();無論如何其中一個需要參數給你的源地址 – EJP 2013-02-22 22:11:25
不,你是對的:你可以在未連接的數據報套接字上使用recvfrom,如果你傳遞適當的參數,你會被告知遠程套接字地址。 – user1752563 2013-02-23 10:02:42