Skip to main content
 首页 » 编程设计

python之选择后没有数据可用于接收

2025年05月04日9bjzhanghao

情况

我使用非阻塞 udp 套接字编写了一个 python 客户端。有时我得到

[Errno 11]资源暂时不可用

据我所知,这是因为我

  • 使用非阻塞套接字
  • 在没有可用数据的非阻塞套接字上执行 recv()

我的代码是这样的:

def doRequestReply(self, addr, msg, readTimeout=2, writeTimeout=2): 
    # Create Socket 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.setblocking(0) 
 
    ... 
    # Send Request 
    ... 
 
    # Wait for Reply 
    readable, _, exceptional = select.select([s], [], [s], readTimeout) 
    if s in readable: 
        data = s.recv(1024) 
 
    ... 
 
    s.close() 

我有时会:

Traceback (most recent call last): 
  File "/home/steffen/Desktop/shared/Monitor/CrawlerWorker.py", line 159, in run 
    if not self.DoPeerExchange(peer, log=True): 
  File "/home/steffen/Desktop/shared/Monitor/CrawlerWorker.py", line 106, in DoPeerExchange 
    msg_rep = self.doRequestReply(addr, msg_req) 
  File "/home/steffen/Desktop/shared/Monitor/CrawlerWorker.py", line 53, in doRequestReply 
    data = s.recv(1024) 
error: [Errno 11] Resource temporarily unavailable 

问题

怎么可能引发异常。我的意思是 select 确保数据已准备好从此套接字读取。我不应该得到这个错误。

我没有在文档中找到任何详细信息。我不想只排除错误,只要我不知道它为什么会发生或它意味着什么。有人知道这种行为吗?

谢谢,

史蒂芬

更新1

服务器部分也使用 udp 非阻塞套接字。只有一个线程正在从此套接字读取数据,在接收数据之前使用 select。

# Create a TCP/IP socket 
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
server.setblocking(0) 
 
while running: 
    readable, _, exceptional = select.select([server], [], [server], 1) 
    if server in readable: 
        # Handle incoming connections 
        data, client_address = server.recvfrom(1024) 
        ... 

大约一个小时后,又得到了:

Traceback (most recent call last): 
  File "Sensor.py", line 87, in main 
    data, client_address = server.recvfrom(1024) 
error: [Errno 11] Resource temporarily unavailable 

select 真的能确保数据可用吗?出现此异常的原因可能是什么?

请您参考如下方法:

尝试:

select.select([s], [], [], readTimeout) 

代替

select.select([s], [], [s], readTimeout) 

来自文档:

select.select(rlist, wlist, xlist[, timeout])

  • rlist: wait until ready for reading
  • wlist: wait until ready for writing
  • xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)

这可能是“异常情况”导致的,具体取决于您的操作系统。您应该只在“ready for reading”上选择。