使用recvfrom()函数无法接收UDP数据的问题求助
UDP监听程序卡在recvfrom的排查与解决
可能的原因及解决方案
1. 参数类型不匹配(首要排查)
你的代码中tempo的类型是int,但recvfrom的最后一个参数要求是socklen_t*(Windows下为unsigned int类型)。类型不匹配可能导致recvfrom无法正确获取源地址信息,进而阻塞无法返回。
修正方式:
将int tempo;改为socklen_t tempo;,保证参数类型与函数要求一致。
2. 网络层面拦截或目标地址错误
- 防火墙拦截:Windows防火墙可能阻止了UDP 3000端口的入站流量。可以临时关闭防火墙测试,或者在防火墙中添加规则,允许你的程序接收UDP 3000端口的数据包。
- 数据源目标地址/端口错误:确认数据源发送的目标IP是本机的实际IP(跨机器场景下不要仅用
localhost),目标端口确实是3000。可以用Wireshark抓包验证是否有UDP包到达本机的3000端口。 - 多网卡场景:如果本机有多个网卡,数据源可能发送到了非当前监听的网卡IP。可以尝试将
information_sur_la_source.sin_addr.s_addr从INADDR_ANY改为具体的网卡IP(比如inet_addr("192.168.1.100")),测试是否能接收数据。
3. 代码错误处理完善
当前代码在WSAStartup失败后仍继续执行后续逻辑,这会导致后续socket操作必然出错。同时recvfrom返回后未检查是否为SOCKET_ERROR,无法排查接收时的具体错误。
修改后的示例代码:
#include <winsock2.h> #include <stdio.h> #pragma comment(lib,"ws2_32.lib") WSADATA initialisation_win32; int erreur; socklen_t tempo; // 修正为socklen_t类型 int nombre_de_caractere; char buffer[65535]; SOCKET id_de_la_socket; SOCKADDR_IN information_sur_la_source; int main (int argc, char* argv[]) { printf("\n监听3000端口\n"); erreur = WSAStartup(MAKEWORD(2,2), &initialisation_win32); if (erreur != 0) { printf("\n无法初始化Winsock,错误码:%d %d", erreur, WSAGetLastError()); return 1; // 初始化失败直接退出 } else printf("\nWSAStartup : OK"); id_de_la_socket = socket(AF_INET, SOCK_DGRAM, 0); if (id_de_la_socket == INVALID_SOCKET) { printf("\n无法创建socket,错误码:%d", WSAGetLastError()); WSACleanup(); return 1; } else printf("\nsocket : OK"); information_sur_la_source.sin_family = AF_INET; information_sur_la_source.sin_addr.s_addr = INADDR_ANY; information_sur_la_source.sin_port = htons(3000); erreur = bind(id_de_la_socket, (struct sockaddr*)&information_sur_la_source, sizeof(information_sur_la_source)); if (erreur != 0) { printf("\n无法绑定端口,错误码:%d %d", erreur, WSAGetLastError()); closesocket(id_de_la_socket); WSACleanup(); return 1; } else printf("\nbind : OK"); tempo = sizeof(information_sur_la_source); printf("\n进入recvfrom阻塞"); nombre_de_caractere = recvfrom(id_de_la_socket, buffer, 1024, 0, (struct sockaddr*)&information_sur_la_source, &tempo); // 检查recvfrom是否出错 if (nombre_de_caractere == SOCKET_ERROR) { printf("\nrecvfrom出错,错误码:%d", WSAGetLastError()); closesocket(id_de_la_socket); WSACleanup(); return 1; } printf("\nrecvfrom返回"); buffer[nombre_de_caractere] = 0; printf("\n收到的数据:%s", buffer); erreur = closesocket(id_de_la_socket); if (erreur != 0) printf("\n无法关闭socket,错误码:%d %d", erreur, WSAGetLastError()); else printf("\nclosesocket : OK"); erreur = WSACleanup(); if (erreur != 0) printf("\n无法清理Winsock,错误码:%d %d", erreur, WSAGetLastError()); else printf("\nWSACleanup : OK"); return 0; }
内容的提问来源于stack exchange,提问作者Seji
相关产品推荐
相关产品推荐

