select.select and socket.setblocking

Francesco Bochicchio bockman at virgilio.it
Wed Dec 31 10:01:11 CET 2008


Grant Edwards ha scritto:
> On 2008-12-30, Francesco Bochicchio <bockman at virgilio.it> wrote:
> 
>> 3. AFAIK (sorry, I feel acronym-ly today ;), there is no difference in 
>> select between blocking and non-blocking mode. The difference is in the
>> recv (again, assuming that you use TCP as protocol, that is AF_INET, 
>> SOCK_STREAM), which in the blocking case would wait to receive all the 
>> bytes that you requested,
> 
> No, in blocking mode it will wait to receive _some_ data (1 or
> more bytes).  The "requested" amount is strictly an upper
> limit: recv won't return more than the requested number of
> bytes, but it might return less.
> 

Uhm. In my experience, with TCP protocol recv only returned less than 
the required bytes if the remote end disconnects. I always check the
returned value of recv and signal an error if the read bytes are less 
than the expected ones, but this error is never occurred (and its about 
20 years that I use sockets in various languages and various flavor of 
unix and occasionally on windows. Maybe  have always been lucky ? :-)

And, on some unices  system call recv also returns when a signal 
interrupts the syscall, but I half-remember reading that python recv in
such a case repeat the system call by itself ... although this might be
only my desire ...

> In non-blocking mode, it will always return immediately, either
> with some data, no data (other end closed), or an EAGAIN or
> EWOULDBLOCK error (I forget which).
> 
>> [...] I myself tend to avoid using non-blocking sockets, since
>> blocking sockets are much easier to handle...
> 
> That depends on whether you can tolerate blocking or not.  In
> an event-loop, blocking is generally not allowed.
> 
What I usually do, when I cannot block is:

- use socket in blocking mode
- do a select with a very small timeout and do a recv only if the select 
returns with input events
- (with TCP) do a recv for the exact amount of bytes that I expect ( 
this mean having a user protocol that carries the message size in the 
header, but this is usually the case ).

This usually worked for me.

If my process (or thread) has only to deal with socket I/O, I make a 
blocking select, and then make an 'exact' recv on whichever socket the 
select signals.

Ciao
----
FB



More information about the Python-list mailing list