选择后没有可用于recv的数据

时间:2014-12-27 13:24:08

标签: python select networking nonblocking recv

情况

我使用非阻塞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

问题

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

我在文档中找不到任何细节。除了错误,我不想只是因为我不知道它为什么会发生或它意味着什么。有谁知道这种行为?

谢谢,

斯特芬

更新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实际上确保数据可用吗?这个例外可能是什么原因?

1 个答案:

答案 0 :(得分:-1)

尝试:

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

而不是

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

来自文档:

  

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

     
      
  • rlist:等到准备好阅读
  •   
  • wlist:等到准备好写作
  •   
  • xlist:等待“异常情况”(请参阅​​手册页,了解系统认为的这种情况)
  •   

根据您的操作系统,我可能会出现“异常情况”。您应该select仅“准备好阅读”。