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

C语言UDP服务器如何判断recv函数返回的网络错误是否致命

recv() 调用常见错误及处理策略

常见非致命错误(不影响后续recv调用,可继续循环接收)

这类错误属于临时异常,套接字本身状态完全正常,错误消除后即可正常接收数据:

  • EINTR:调用过程被系统信号中断,属于常见临时错误,直接重试即可
  • EAGAIN/EWOULDBLOCK:仅套接字设置为非阻塞模式时会触发,表示当前无可用数据,等待后重试即可
  • ENOBUFS:系统网络缓冲区临时不足,属于资源紧张类临时问题,恢复后即可正常工作
  • ENOMEM:内核内存临时不足,同样属于资源类临时问题,不影响套接字本身可用性

常见致命错误(后续recv完全无法正常执行,必须跳出循环)

这类错误代表套接字本身状态异常、或者传入参数非法,继续调用recv也只会持续报错:

  • EBADF:传入的文件描述符无效,要么套接字已被提前关闭,要么参数传入错误
  • EFAULT:buf指针指向的用户态内存空间非法,属于代码逻辑错误,无法通过重试解决
  • EINVAL:套接字已被调用shutdown关闭了接收通道,或者传入参数非法,套接字状态异常
  • ENOTSOCK:传入的文件描述符不是套接字类型,参数错误,套接字不可用
  • ENOTCONN:UDP无连接场景下极少出现,仅当该套接字提前调用connect绑定了无效对端时才会触发,套接字状态异常

代码修改建议

你现有代码的逻辑会把所有错误都判定为致命错误直接退出,会导致很多临时异常触发服务不必要的下线,建议调整为如下逻辑:

while(1) {
    ssize_t recv_len = recv(s, buf, sizeof(buf), 0);
    if (recv_len < 0) {
        // 匹配非致命错误则跳过,继续接收
        if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK 
            || errno == ENOBUFS || errno == ENOMEM) {
            continue;
        }
        // 其余为致命错误,记录错误码后退出
        rc = errno;
        break;
    } 
    //TODO: process buf... 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:06:04