non-blocking sockets

Noah noah at noah.org
Tue Apr 23 13:57:00 EDT 2002


You probably get an IOError or an OSError.
You should be able to catch any generic exception
(see the code at the end).

Getting an exception on a non-blocking read is
normal behavior. This is how Python tells you that
the there was no data to read. Generally you should
use 'select' before you try to call a non-blocking read,
but there are times when you may want to do this.

If we assume that this is the case then what you are getting 
is an IOError or OSError because an behind-the-scenes system call
set errno to be not zero. I am not sure how setblocking(0) works, 
but it probably sets the O_NONBLOCK flag on the file descriptor
(which you can also do using the fcntl module).
At the system level when you have O_NONBLOCK set on a socket and 
you try to read from an empty socket then read() returns -1 and 
sets errno to EAGAIN.
The problem is that Python interprets errno as an exception, 
(well, not really a problem, just a better way of looking at it...)
When a Python function calls the underlying system function
if that system function sets errno to be not zero 
then Python will throw an exception. The trick is that you can 
get different exceptions depending on how you call read -- 
depsite the fact that the same low-level system function is being called. 
If you call os.read() then you may get an OSError.
If you call Python's regular read then you may get an IOError.
I am not sure what you may get if you call the Socket Object methods.

Fortunately we have the errno module, so when you get an
exception you can check the errno value. The exception object
that you catch will have an errno attribute. Just compare that value
to the contstants in the errno module. For example:
	except IOError, ex:
		if ex.errno == errno.EAGAIN

Try this code. Let me know if this makes things more clear:

	import errno

        try:
                read_foo (my_socket)   ### YOUR STUFF HERE
        except OSError, e:
                print e.str()
                print 'errno:', e.errno
                if e.errno == errno.EAGAIN:
                        print 'OSError: EAGAIN'
        except IOError, e:
                print e.str()
                print 'errno:', e.errno
                if e.errno == errno.EAGAIN:
                        print 'IOError: EAGAIN'
        except Exception, e:
                print e.str()
                print 'errno:', e.errno
                print 'Something else happened!'

Yours,
Noah



-----Original Message-----
From: python-list-admin at python.org
[mailto:python-list-admin at python.org]On Behalf Of so very tired
Sent: Tuesday, April 23, 2002 8:01 AM
To: python-list at python.org
Subject: non-blocking sockets


When trying to read from a socket, I don't want it hanging, so I set it to
non-blocking by calling

setblocking(0)

but then when I try to read from it and there is no data in the socket, I
get an error. I tried this in both windows and linux and in both I get an
error and the program stops. It says there's an exception but it doesn't
say the name of the exception so I can't even try to catch.
Does anyone know how I can check if there's data coming from a socket
connection without hanging or having the program barf on me?
Thanks.
mRiaz








More information about the Python-list mailing list