Sending Binary Data¶
Sockets transmit streams of bytes. Those bytes can contain text messages, as in the previous examples, or they can be made up of binary data that has been encoded for transmission. To prepare binary data values for transmission, pack them into a buffer with struct.
This client program encodes an integer, a string of two characters, and a floating point value into a sequence of bytes that can be passed to the socket for transmission.
import binascii import socket import struct import sys # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('localhost', 10000) sock.connect(server_address) values = (1, 'ab', 2.7) packer = struct.Struct('I 2s f') packed_data = packer.pack(*values) try: # Send data print >>sys.stderr, 'sending "%s"' % binascii.hexlify(packed_data), values sock.sendall(packed_data) finally: print >>sys.stderr, 'closing socket' sock.close()
The server program uses the same Struct specifier to unpack the bytes it receives.
import binascii import socket import struct import sys # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('localhost', 10000) sock.bind(server_address) sock.listen(1) unpacker = struct.Struct('I 2s f') while True: print >>sys.stderr, '\nwaiting for a connection' connection, client_address = sock.accept() try: data = connection.recv(unpacker.size) print >>sys.stderr, 'received "%s"' % binascii.hexlify(data) unpacked_data = unpacker.unpack(data) print >>sys.stderr, 'unpacked:', unpacked_data finally: connection.close()
Running the client produces:
$ python ./socket_binary_client.py sending "0100000061620000cdcc2c40" (1, 'ab', 2.7) closing socket
And the server shows the values it receives:
$ python ./socket_binary_server.py waiting for a connection received "0100000061620000cdcc2c40" unpacked: (1, 'ab', 2.700000047683716) waiting for a connection
The floating point value loses some precision as it is packed and unpacked, but otherwise the data is transmitted as expected. One thing to keep in mind is that depending on the value of the integer, it may be more efficient to convert it to text and then transmit, instead of using struct. The integer 1 uses one byte when represented as a string, but four when packed into the structure.
- Converting between strings and other data types.