For example, although the socket model is limited to transferring byte strings, you can
send and receive nearly arbitrary Python objects with the standard library pickle object
serialization module. Its dumps and loads calls convert Python objects to and from byte
strings, ready for direct socket transfer:
>>> import pickle
>>> x = pickle.dumps([99, 100]) # on sending end... convert to byte strings
>>> x # string passed to send, returned by recv
b'\x80\x03]q\x00(KcKde.'
>>> pickle.loads(x) # on receiving end... convert back to object
[99, 100]
For simpler types that correspond to those in the C language, the struct module pro-
vides the byte-string conversion we need as well:
>>> import struct
>>> x = struct.pack('>ii', 99, 100) # convert simpler types for transmission
>>> x
b'\x00\x00\x00c\x00\x00\x00d'
>>> struct.unpack('>ii', x)
(99, 100)
When converted this way, Python native objects become candidates for socket-based
transfers. See Chapter 4 for more on struct. We previewed pickle and object seriali-
zation in Chapter 1, but we’ll learn more about it and its few pickleability constraints
when we explore data persistence in Chapter 17.
In fact there are a variety of ways to extend the basic socket transfer model. For instance,
much like os.fdopen and open for the file descriptors we studied in Chapter 4, the
socket.makefile method allows you to wrap sockets in text-mode file objects that han-
dle text encodings for you automatically. This call also allows you to specify nondefault
Unicode encodings and end-line behaviors in text mode with extra arguments in 3.X
just like the open built-in function. Because its result mimics file interfaces, the
socket.makefile call additionally allows the pickle module’s file-based calls to transfer
objects over sockets implicitly. We’ll see more on socket file wrappers later in this
chapter.
For our simpler scripts here, hardcoded byte strings and direct socket calls do the job.
After talking with a given connected client, the server in Example 12-1 goes back to its
infinite loop and waits for the next client connection request. Let’s move on to see what
happened on the other side of the fence.
Client socket calls
The actual socket-related calls in client programs like the one shown in Exam-
ple 12-2 are even simpler; in fact, half of that script is preparation logic. The main thing
to keep in mind is that the client and server must specify the same port number when
opening their sockets and the client must identify the machine on which the server is
792 | Chapter 12: Network Scripting