Jump to content
  • Advertisement
Sign in to follow this  
Red Ant

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

This topic is 4679 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!