[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Making Sockets Look Like Files and Streams


So far in this chapter, we’ve focused on the role of sockets in the classic client/server
networking model. That’s one of their primary roles, but they have other common use
cases as well.


In Chapter 5, for instance, we saw sockets as a basic IPC device between processes and
threads on a single machine. And in Chapter 10’s exploration of linking non-GUI scripts
to GUIs, we wrote a utility module (Example 10-23) which connected a caller’s standard
output stream to a socket, on which a GUI could listen for output to be displayed.
There, I promised that we’d flesh out that module with additional transfer modes once
we had a chance to explore sockets in more depth. Now that we have, this section takes
a brief detour from the world of remote network servers to tell the rest of this story.


Although some programs can be written or rewritten to converse over sockets explicitly,
this isn’t always an option; it may be too expensive an effort for existing scripts, and
might preclude desirable nonsocket usage modes for others. In some cases, it’s better
to allow a script to use standard stream tools such as the print and input built-in
functions and sys module file calls (e.g., sys.stdout.write), and connect them to sock-
ets only when needed.


Because such stream tools are designed to operate on text-mode files, though, probably
the biggest trick here is fooling them into operating on the inherently binary mode and
very different method interface of sockets. Luckily, sockets come with a method that
achieves all the forgery we need.


The socket object makefile method comes in handy anytime you wish to process a
socket with normal file object methods or need to pass a socket to an existing interface
or program that expects a file. The socket wrapper object returned allows your scripts
to transfer data over the underlying socket with read and write calls, rather than recv
and send. Since input and print built-in functions use the former methods set, they will
happily interact with sockets wrapped by this call, too.


The makefile method also allows us to treat normally binary socket data as text instead
of byte strings, and has additional arguments such as encoding that let us specify non-
default Unicode encodings for the transferred text—much like the built-in open and
os.fdopen calls we met in Chapter 4 do for file descriptors. Although text can always
be encoded and decoded with manual calls after binary mode socket transfers, make
file shifts the burden of text encodings from your code to the file wrapper object.


This equivalence to files comes in handy any time we want to use software that supports
file interfaces. For example, the Python pickle module’s load and dump methods expect
an object with a file-like interface (e.g., read and write methods), but they don’t require
a physical file. Passing a TCP/IP socket wrapped with the makefile call to the pickler
allows us to ship serialized Python objects over the Internet, without having to pickle
to byte strings ourselves and call raw socket methods manually. This is an alternative
to using the pickle module’s string-based calls (dumps, loads) with socket send and


Making Sockets Look Like Files and Streams | 827
Free download pdf