3
votes

Situation

I write a python client using nonblocking udp sockets. Sometimes I get

[Errno 11] Resource temporarily unavailable

As far as I know, this happens because I

  • Use nonblocking sockets
  • recv() on a nonblocking socket that has no data available

My code is this:

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()

I sometimes get:

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

Question

How is it possible that the exception can be raised. I mean select ensures data is ready to be read from this socket. I should not get this error.

I dont find any details in the docs. I dont want to just except the error as long as I dont know why it happens or what it means. Does anyone knows about this behaviour?

Thanks,

Steffen

Update 1

The server part also uses udp nonblocking sockets. Only one thread is reading from this socket, using select before receiving data.

# 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)
        ...

After about an hour the got again:

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

Does select actually ensures data will be available? What could be a reason for this exception?

1
Are there multiple processes reading from the same socket?Barmar
I think this cannot be. As you see I create the socket in the function and close it before leaving. The socket is not sharedSteffen
I saw that, but sometimes the code people post here is abbreviated from the real thing.Barmar
I now finished the server part. Again, I see the same issue. Only the main thread is reading from the socket in a loop!Steffen

1 Answers

-1
votes

Try:

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

instead of

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

From the documentation:

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)

It might me that an "exceptional condition" is causing this, depending on your operating system. You should select only on "ready for reading".