[Python-Dev] Non-blocking sockets, asynchronous connects and select.select.

Alan Kennedy python-dev at alan.kennedy.name
Tue Mar 20 01:26:07 CET 2007


Dear all,

I'm working on a select implementation for jython (in combination with
non-blocking sockets), and a set of unit tests for same.

I decided to run all of the non-blocking unit tests, both server and
client side, in the same thread; seems to be a reasonable thing to do.
After all, avoiding threads is one of the great benefits of
non-blocking sockets.

Also, I'm writing the tests so that they'll hopefully pass on both
cpython and jython.

But I'm getting behaviour I don't expect on cpython, when a
non-blocking accept and connect_ex is used, for the server and client
sides respectively.

The following piece of code outputs what I expect on my jython
implementation, which is that both the server accept and client write
calls would NOT block.

But when I run the code on cpython, the code reports that both calls
would block, i.e. that neither side of the socket will progress with
the connection.

The code is

# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
import socket
import select

SERVER_ADDRESS = ("", 54321)

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setblocking(0)
server_socket.bind(SERVER_ADDRESS)
server_socket.listen(5)

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setblocking(0)

result = client_socket.connect_ex(SERVER_ADDRESS)

rfds, wfds, xfds = select.select([server_socket], [client_socket], [], 1)
if server_socket in rfds:
    print "Server socket: accept would not block"
else:
    print "Server socket: accept would block"
if client_socket in wfds:
    print "Client socket: write would not block"
else:
    print "Client socket: write would block"

server_socket.close()
client_socket.close()
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Is there some call that I am missing, e.g. something along the lines
of the java finishConnect() method on SocketChannel?

http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SocketChannel.html#finishConnect()

Is there any way to make the above code report, on cpython, that
neither side of the socket would block?

Am I missing some essential method call that would make either side
progress to a connected socket?

Thanks,

Alan.


More information about the Python-Dev mailing list