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
What is the purpose of the thread?
Sign in to comment