yang
yang

Reputation: 151

non-blocking socket,error is always

sock.setblocking(0)
try:
    data = sock.recv(1024)
 except socket.error, e:
    if e.args[0] == errno.EWOULDBLOCK: 
          print 'EWOULDBLOCK'
else:            
   if not data:   #recv over
      sock.close()
      print 'close================='       
   else:
      print 'recv ---data---------'
      poem += data

all above code is in a loop.using non-blocking socket(just want to test 'non-blocking socket') to get data. But always print 'EWOULDBLOCK',i don't know why?

Upvotes: 10

Views: 26350

Answers (2)

xiaowl
xiaowl

Reputation: 5207

The exception is raised by design, cause you are using non-blocking IO.

The major mechanical difference is that send, recv, connect and accept can return without having done anything. You have (of course) a number of choices. You can check return code and error codes and generally drive yourself crazy.

Quoted from Python doc

If you run man errno 3, you shall see the description of EWOULDBLOCK. The exception is reasonable, because there is no data to read yet.

Upvotes: 3

mhawke
mhawke

Reputation: 87054

The socket is non-blocking so recv() will raise an exception if there is no data to read. Note that errno.EWOULDBLOCK = errno.EAGAIN = 11. This is Python's (well the OS really) way of telling you to try the recv() again later.

I note that you close the socket each time you get this exception. That's not going to help at all. Your code should be something like this:

import socket, errno, time

sock = socket.socket()
sock.connect(('hostname', 1234))
sock.setblocking(0)

while True:
    try:
        data = sock.recv(1024)
        if not data:
            print "connection closed"
            sock.close()
            break
        else:
            print "Received %d bytes: '%s'" % (len(data), data)
    except socket.error, e:
        if e.args[0] == errno.EWOULDBLOCK: 
            print 'EWOULDBLOCK'
            time.sleep(1)           # short delay, no tight loops
        else:
            print e
            break

For this sort of thing, the select module is usually the way to go.

Upvotes: 16

Related Questions