You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:55:32