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

为何我的UDP接收代码无法获取数据包?请求技术排查

问题分析

我编写了一段UDP接收代码,需要从IP为192.168.10.2的源端接收1000个大小为4094的数据包。通过Wireshark确认数据包已经到达我的主机(192.168.10.1),数据包的源端口为1234、目的端口为4321,但代码在recvfrom处挂起。请问以下代码片段是否存在使用错误?

int sockfd;
char buffer[4094];
struct sockaddr_in servaddr, cliaddr;

FILE* f = fopen("output.bin", "wb");

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
    perror("error creating socket");
    exit(EXIT_FAILURE);

}

memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));

servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(4321);
servaddr.sin_addr.s_addr = inet_addr("192.168.10.2");

bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr));

int n;
socklen_t len;

for (int i=0; i<1000; i++){
    len = sizeof(cliaddr);
    n = recvfrom(sockfd, (char *)buffer, 4094, MSG_WAITALL, 
                 (struct sockaddr *) &cliaddr, &len);
    if (n>0){
        if (n<4094){
            buffer[n] = '\0';
        }
        fwrite(buffer, 1, n, f);
    }
}

fclose(f);
close(sockfd);

错误点分析

  • Bind地址错误:你在bind时将socket绑定到了源端IP(192.168.10.2),但你的主机IP是192.168.10.1。这会导致socket仅监听发送到192.168.10.2地址的数据包,到达你主机192.168.10.1的数据包会被直接忽略。正确做法是绑定到INADDR_ANY(允许接收发送到主机任何IP的数据包),或者明确绑定到你的主机IP:

    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    // 或者
    servaddr.sin_addr.s_addr = inet_addr("192.168.10.1");
    
  • MSG_WAITALL选项误用:MSG_WAITALL是为TCP设计的选项,用于确保接收指定长度的流式数据。但UDP是基于数据包的协议,每个recvfrom调用只能接收一个完整的UDP数据包,使用MSG_WAITALL没有实际意义,反而可能引发异常行为,建议移除该选项:

    n = recvfrom(sockfd, (char *)buffer, 4094, 0, 
                 (struct sockaddr *) &cliaddr, &len);
    
  • 缺失错误处理:代码未处理recvfrom返回-1的错误情况(比如socket异常),可能导致程序无限挂起或异常退出,建议添加错误处理逻辑,例如:

    n = recvfrom(sockfd, (char *)buffer, 4094, 0, 
                 (struct sockaddr *) &cliaddr, &len);
    if (n == -1) {
        perror("recvfrom failed");
        fclose(f);
        close(sockfd);
        exit(EXIT_FAILURE);
    }
    

内容的提问来源于stack exchange,提问作者grumio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:23:10