梦想还在,生活当继续!
一、前言
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 unavailable,errno代码为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, EWOULDBLOCK和 EINPROGRESS。”
linux 下,BlockingIOError: [Errno 11] 即为 EAGAIN 错误。
windows上,EAGAIN的名字叫做EWOULDBLOCK。对应的报错信息为:
“BlockingIOError: [WinError 10035]无法立即完成一个非阻止性套接字操作”。

本文详细分析了Python3中使用非阻塞socket通信时遇到的BlockingIOError: [Errno 11]错误,通过复现错误、原因分析和解决方案探讨,解释了该错误与资源不可用的关系,并提供了相应的错误处理策略。
最低0.47元/天 解锁文章
1133

被折叠的 条评论
为什么被折叠?



