linux udp 广播recvfrom 返回 -1 错误码是 11 EAGAIN Resource temporarily unavailable

在运行银河麒麟桌面操作系统V10(SP1),内核Linux5.4.18的环境中,遇到UDP广播接收问题。当尝试接收255.255.255.255的数据时,使用recvfrom函数返回-1,错误码为11(EAGAIN)。经排查,关闭防火墙和将bind绑定到INADDR_ANY(0.0.0.0)可以解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

版本:银河麒麟桌面操作系统V10(SP1)
内核:Linux 5.4.18-28.23-bj-generic
CPU:Loongson-3A5000

架构:loongarch64-linux-gnu

遇到问题:

udp 收广播 255.255.255.255 数据时收不到,在 wireshark 抓包可以看到 数据
recvfrom 返回 -1 错误码是 11  EAGAIN   Resource temporarily unavailable .

解决:
1、关闭防火墙 
2、bind 绑定IP到广播地址INADDR_ANY 0.0.0.0 

### 关于 Bind 函数错误码 99 (`Cannot assign requested address`) 的原因与解决方案 错误 `OSError: [Errno 99] Cannot assign requested address` 表明在调用 `bind()` 函数时,尝试绑定到的地址或端口存在问题。这种错误的主要原因包括以下几个方面: 1. **指定的 IP 地址无效或不可用**:如果指定了一个不存在或未分配给本机的 IP 地址,则会触发此错误[^1]。 2. **重复绑定同一地址和端口**:在同一进程中多次调用 `bind()` 并试图绑定相同的本地地址和端口号可能导致冲突[^3]。 3. **IP 地址处于 Tentative 状态**:对于 IPv6 地址,当其状态为 Tentative 时,操作系统不允许对其进行绑定操作,直到它变为 Preferred 状态为止[^4]。 #### 解决方案 - **验证目标地址的有效性**:确保所要绑定的 IP 和端口是合法且可用的。可以通过命令行工具如 `ping`, `netstat`, 或者 `ss` 来验证特定端口的状态以及是否可以被监听。 - **设置 SO_REUSEADDR 选项**:为了防止因快速连续启动服务而导致的竞争条件,可以在创建新的套接字之前设置 `SO_REUSEADDR` 选项允许重新利用已经被关闭但仍处 TIME_WAIT 状态中的地址/端口组合: ```python import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置可复用标志位 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: sock.bind(('your_ip', your_port)) except Exception as e: print(f"Bind failed with error {e}") finally: sock.close() ``` - **处理 Tentative Address**:等待一段时间再重试绑定过程通常能够解决问题。另一种方式是在应用程序层面实现超时机制以便自动跳过暂时性的 tentativeness[^4]。 --- ### 关于 Recvfrom 函数错误码 11 (`Resource temporarily unavailable`) 的原因与解决方案 错误 `errno.EAGAIN` (Error code 11) 在使用非阻塞模式下的 `recvfrom()` 函数时较为常见,表示当前没有数据可供读取。这并不是真正的错误,而是表明需要稍后再试。 #### 原因分析 1. **非阻塞模式下无数据到达**:当套接字设置为非阻塞模式(`setblocking(False)`)时,如果没有数据包到达缓冲区,`recvfrom()` 将立即返回并抛出 `EAGAIN` 错误[^5]。 2. **网络拥塞或其他延迟因素**:由于网络状况不佳或者其他外部因素导致的数据传输延迟能够间接引发这个问题。 #### 解决方案 - **切换至阻塞模式**:如果不希望频繁轮询检查是否有新数据到来,可以把套接字设回默认的阻塞模式(`setblocking(True)`), 这样只有实际收到消息之后才会继续执行后续代码片段. - **采用 select/poll 方法监控描述符状态变化**:通过引入更高级别的 I/O 多路复用技术比如 `select.select()`, `poll.poll()`, 或者异步框架如 asyncio 可有效管理多个连接的同时避免不必要的 CPU 循环消耗: ```python import socket import select s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setblocking(False) ready_to_read, _, _ = select.select([s], [], []) if ready_to_read: data, addr = s.recvfrom(1024) else: pass # Handle no-data scenario gracefully here... ``` --- ### 总结 综合来看,针对 `bind()` 出现的错误码 99 应着重核查绑定的目标地址合法性及其唯一性;而对于 `recvfrom()` 抛出的 EAGAIN 则需理解这是非阻塞 IO 下正常的行为表现之一,并据此调整程序逻辑适应不同情形下的需求差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值