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
相关产品推荐
相关产品推荐

