select.select and socket.setblocking

Grant Edwards grante at visi.com
Wed Dec 31 11:28:30 EST 2008


On 2008-12-31, Francesco Bochicchio <bockman at virgilio.it> wrote:
> 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've no idea how you got recv() to behave that way, because
I've never seen it do that.  Take a look at the echo
client/server examples at http://docs.python.org/library/socket.html.

If recv worked the way you claimed it did, those programs
wouldn't work -- they would deadlock.  But, that example does
work.

In that example, the server program calls recv(1024), and yet
it returns 12 bytes.

The manual page for recv() specifically states that the "len"
parameter is a maximum:

   The maximum amount of data to be received at once is specified
   by bufsize. See the Unix manual page recv(2) for the meaning of
   the optional argument flags; it defaults to zero.

   Note: For best match with hardware and network realities, the value
         of bufsize should be a relatively small power of 2, for
         example, 4096.

The Linux man page for recv() also says len is the length of
the receive buffer and is an upper limit on the number of bytes
to read.

Can you post an example program that exhibits the behavior you
describe?


> [...]

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

Yes that will usually (almost always) work.  But, IIRC, there
are theoretically situraitons where something happens after
select returns and before you call recv() that could cause
recv() to block.

-- 
Grant Edwards




More information about the Python-list mailing list