ActiveState Code

Recipe 525487: Extending socket.socketpair() to work on Windows


This recipe wraps socketpair() to provide a standard socket pair on POSIX systems or a pair of connected sockets using ephemeral ports on Windows.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from socket import *
import threading

try:
    pairfamily = AF_UNIX
except NameError:
    pairfamily = AF_INET

def SocketPair(family=pairfamily, type_=SOCK_STREAM, proto=IPPROTO_IP):
    """Wraps socketpair() to support Windows using local ephemeral ports"""
    try:
        sock1, sock2 = socketpair(family, type_, proto)
        return (sock1, sock2)
    except NameError:
        listensock = socket(family, type_, proto)
        listensock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        listensock.bind( ('localhost', 0) )
        iface, ephport = listensock.getsockname()
        listensock.listen(1)

        sock1 = socket(family, type_, proto)
        connthread = threading.Thread(target=pairConnect, args=[sock1, ephport])
        connthread.setDaemon(1)
        connthread.start()
        sock2, sock2addr = listensock.accept()
        listensock.close()
        return (sock1, sock2)

def pairConnect(sock, port):
    sock.connect( ('localhost', port) )

Discussion

During the development of a recent project, the need arose to handle threads and IPC in a manner that is supported under both POSIX and Windows. Since the threads were part of a network server, the solution presented itself in the form of select.select() and socket pairs. The threads could block in select() while waiting for events from the client socket or notification, via the socket pair, from other threads. However, windows doesn't support socket.socketpair() or AF_UNIX sockets, so I wrote this wrapper.

Comments

  1. 1. At 1:16 p.m. on 21 oct 2009, James Burgess said:

    What is the purpose of the thread?

Sign in to comment