Emulating socketpair() on systems where it isn't implemented

Started by
0 comments, last by Red Ant 18 years, 7 months ago
Hi again, I need the socketpair() function in one my Python projects to create a pair of connected sockets. I intend to use them to communicate between 2 threads. Anyway, the problem is that socketpair() is only implemented on UNIX, and I need this program to work on both UNIX and Windows. So I thought to myself, well let's just roll our own socketpair() then ... shouldn't be too hard, right? Essentially all it takes is to set up a temporary server socket on localhost, connect to it, and have the server socket accept the incoming connection. Voila, there you go, 2 nicely connected sockets. So much for the theory. Now here's the code (does this thiny work for Python code??)

import socket
import select


def createSocketpair( nUsePortnumberToEmulateSocketpair ):
    # See if socketpair() is available.
    bSocketpairImplemented = True
    try:
        hIPCConnectionEnd0, hIPCConnectionEnd1 = socket.socketpair( socket.AF_INET, socket.SOCK_STREAM )
    except AttributeError:
        # If we get this exception, that means socketpair() is not implemented, so we need to emulate it.
        bSocketpairImplemented = False

    if bSocketpairImplemented == True:
        return hIPCConnectionEnd0, hIPCConnectionEnd1
    
    # Create an IPC socket and set it to nonblocking mode.
    hIPCConnectionEnd0 = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
    hIPCConnectionEnd0.setblocking( 0 )

    # Create a temporary server socket and make it non-blocking. Bind it to the port number
    # we've been given and set it up to listen for incoming connections.
    hTempServerSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
    hTempServerSocket.setblocking( 0 )
    hTempServerSocket.bind( ( '', nUsePortnumberToEmulateSocketpair ) )
    hTempServerSocket.listen( 1 )

    try:
        hIPCConnectionEnd0.connect( ( '', nUsePortnumberToEmulateSocketpair ) )
    except socket.error, TheError:
        # Error 10035 (operation would block) is not an error, as we're doing this with a non-blocking socket.
        if TheError[ 0 ] != 10035:
           raise 
        
    # Use select to wait up to 4 seconds for the connect() to succeed.
    vMonitorReadable = [ hTempServerSocket ]

    vReadable, vWriteable, vInError = select.select( vMonitorReadable, [], [], 4.0 )

    # See if the connect worked.
    if not hTempServerSocket in vReadable:
        print "Damn, server socket not in set of readable sockets."
        #raise socket.timeout


    # If we reach this line, the connect() must have succeeded. We can now call accept().
    hhIPCConnectionEnd1, tAddress = hTempServerSocket.accept()

    return ( hIPCConnectionEnd0, hhIPCConnectionEnd1 )

    
# Just a little list.
createSocketpair( 20000 )



But for some reason select() always times out without any activity on the server socket at all. For some reason my connect() doesn't seem to work, and I just don't see why. =(
Advertisement
Ah shoot, solved the problem minutes after posting my thread (even tho I had previously fiddled with it for hours ... grrr).


Instead of supplying an empty string in the bind() and connect() calls (I recall having seen a code sample that stated an empty string was equivalent to the localhost address), I simply specified '127.0.0.1', which works like a charm.

This topic is closed to new replies.

Advertisement