梦想还在,生活当继续!
一、前言
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]
无法立即完成一个非阻止性套接字操作”。
官网的这个说明,依然没让我明白为什么会出现“资源不可用”。但它大概描述了如