Non-blocking connect

Jean-Paul Calderone exarkun at divmod.com
Fri May 2 15:53:59 EDT 2008


On Fri, 02 May 2008 14:38:47 -0400, Roy Smith <roy at panix.com> wrote:
>In article
><1029ba0a-74e0-41d3-8397-7e326f4611bf at a9g2000prl.googlegroups.com>,
> mp <mailpitches at email.com> wrote:
>
>> Thanks Roy. I was just trying to understand someone else's code, but
>> in the end it turns out that this was just a bug.
>>
>> What weirded me out was how injecting a print statement preventing the
>> error from occurring, but now I get it. Without blocking, the
>> connection handshake occurs in parallel after the connect_exc method
>> is called. In my example, my processor reaches the send call before
>> the connection manages to complete in the background. However, if you
>> stick in a print statement after the connect_exc call and before the
>> send call, it delays processing just long enough for the connection to
>> complete, thus no exception is thrown by the send call.
>
>I don't really understand that last part.  There shouldn't be any
>background processing going on, unless there's a lot more code than you
>showed.
>
>The three-way handshake *can't* happen in the background, because
>connect_ex() has no way to know what value to return until the handshake is
>completed.  Let's say I send a SYN, and 15 seconds later, you send a RST
>(indicating that the connection has been refused).  The connect_ex() call
>has to have waited the 15 seconds for this to happen so it knows to return
>an appropriate error code.
>
>I do not understand why sticking a print statement in there should make any
>difference.

The background processing is going on in the kernel, where the TCP/IP
implementation is.  After userspace has indicated the desire to establish
a connection, the kernel doesn't need any further input in order to set
up that connection.  So non-blocking connect_ex starts the process and the
process will complete on its own (successfully or with an error) without
any further socket calls from the userspace application.

The right way to know when the connect attempt has actually completed
(successfully or with an error) is to use a mechanism like select() to
check for writeability.  Once the socket is writeable, if it has a 0
SO_ERROR, the connection was successful, otherwise it failed.

Jean-Paul



More information about the Python-list mailing list