python3「非阻塞socket」报错 “BlockingIOError: [Errno 11]“ 复现以及分析解决

梦想还在,生活当继续!

一、前言

linux 下,用 python 的非阻塞 socket 通信时,遇到了 BlockingIOError: [Errno 11] Resource temporarily unavailable 错误。

翻译报错信息 Resource temporarily unavailable 为:“资源暂时不可用”。

在我的代码里,使用了“epoll + 非阻塞 socket” 的模式。因此猜测,在有 socket 还未创建完成的情况下,使用它发送消息导致报错,错误的理解为这个 socket 资源暂时不可用。-.-

后来上网查找相关资料,发现并非如此。根据网上资料,我得到两种不同的答案。

答案一:

首先,是我把套接字设置为异步的。然后,在使用 write 发送数据时采取的方式是循环发送大量的数据;由于是异步的,write\send 将要发送的数据提交到发送缓冲区后是立即返回的,并不需要对端确认数据已接收。在这种情况下是很有可能出现发送缓冲区被填满,导致 write\send 无法再向缓冲区提交要发送的数据。因此就产生了 Resource temporarily unavailable 的错误。EAGAIN 的意思也很明显,就是要你再次尝试。

答案二:

Linux 进行非阻塞的 socket 接收数据时经常出现 Resource temporarily unavailableerrno 代码为11(EAGAIN),这是什么意思?
这表明你在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏 socket 的同步,不用管它,下次循环接着 recv 就可以。

两种答案不同,但是感觉都很有道理。这让我迷惑了,于是决定自己研究研究。记录下来,分享的同时,也方便自己以后回顾。

二、BlockingIOError

首先,我想知道 python 中的 BlockingIOError 具体指什么。
python 官方文档中,找到了对 BlockingIOError 异常的说明,如下:

exception BlockingIOError:

Raised when an operation would block on an object (e.g. socket) set for non-blocking operation. Corresponds to errno EAGAIN, EALREADY, EWOULDBLOCK and EINPROGRESS.

我将它翻译为:“当在设置为非阻塞操作的对象(例如:套接字)上,执行阻塞操作时触发。对应的错误类型有:EAGAIN, EALREADY, EWOULDBLOCKEINPROGRESS。”

linux 下,BlockingIOError: [Errno 11] 即为 EAGAIN 错误。

windows 上,EAGAIN 的名字叫做 EWOULDBLOCK。对应的报错信息为:
BlockingIOError: [WinError 10035] 无法立即完成一个非阻止性套接字操作”。

官网的这个说明,依然没让我明白为什么会出现“资源不可用”。但它大概描述了如何触发 EAGAIN

  • 53
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的一天

~呀哈,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值