recv calls, and might offer more flexibility for software that must support a variety of
transport mechanisms. See Chapter 17 for more details on object serialization
interfaces.
More generally, any component that expects a file-like method protocol will gladly
accept a socket wrapped with a socket object makefile call. Such interfaces will also
accept strings wrapped with the built-in io.StringIO class, and any other sort of object
that supports the same kinds of method calls as built-in file objects. As always in Python,
we code to protocols—object interfaces—not to specific datatypes.
A Stream Redirection Utility
To illustrate the makefile method’s operation, Example 12-10 implements a variety of
redirection schemes, which redirect the caller’s streams to a socket that can be used by
another process for communication. The first of its functions connects output, and is
what we used in Chapter 10; the others connect input, and both input and output in
three different modes.
Naturally, the wrapper object returned by socket.makefile can also be used with direct
file interface read and write method calls and independently of standard streams. This
example uses those methods, too, albeit in most cases indirectly and implicitly through
the print and input stream access built-ins, and reflects a common use case for the tool.
Example 12-10. PP4E\Internet\Sockets\socket_stream_redirect.py
"""
###############################################################################
Tools for connecting standard streams of non-GUI programs to sockets that
a GUI (or other) program can use to interact with the non-GUI program.
###############################################################################
"""
import sys
from socket import *
port = 50008 # pass in different port if multiple dialogs on machine
host = 'localhost' # pass in different host to connect to remote listeners
def initListenerSocket(port=port):
"""
initialize connected socket for callers that listen in server mode
"""
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(('', port)) # listen on this port number
sock.listen(5) # set pending queue length
conn, addr = sock.accept() # wait for client to connect
return conn # return connected socket
def redirectOut(port=port, host=host):
"""
connect caller's standard output stream to a socket for GUI to listen
start caller after listener started, else connect fails before accept
828 | Chapter 12: Network Scripting