Автор оригинала: Doug Hellmann.
Сокеты передают потоки байтов. Эти байты могут содержать текстовые сообщения, закодированные в байты, как в предыдущих примерах, или они могут состоять из двоичных данных, которые были упакованы в буфер с помощью структуры, чтобы подготовить их к передаче.
Эта клиентская программа кодирует целое число, строку из двух символов и значение с плавающей запятой в последовательность байтов, которая может быть передана в сокет для передачи.
socket_binary_client.py
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, b'ab', 2.7) packer struct.Struct('I 2s f') packed_data packer.pack(*values) print('values =', values) try: # Send data print('sending {!r}'.format(binascii.hexlify(packed_data))) sock.sendall(packed_data) finally: print('closing socket') sock.close()
При отправке многобайтовых двоичных данных между двумя системами важно убедиться, что обе стороны соединения знают, в каком порядке находятся байты и как собрать их обратно в правильный порядок для локальной архитектуры. Серверная программа использует тот же спецификатор Struct
для распаковки полученных байтов, чтобы они интерпретировались в правильном порядке.
socket_binary_server.py
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('\nwaiting for a connection') connection, client_address sock.accept() try: data connection.recv(unpacker.size) print('received {!r}'.format(binascii.hexlify(data))) unpacked_data unpacker.unpack(data) print('unpacked:', unpacked_data) finally: connection.close()
Запуск клиента производит:
$ python3 source/socket/socket_binary_client.py values = (1, b'ab', 2.7) sending b'0100000061620000cdcc2c40' closing socket
И сервер показывает полученные значения:
$ python3 socket_binary_server.py waiting for a connection received b'0100000061620000cdcc2c40' unpacked: (1, b'ab', 2.700000047683716) waiting for a connection
Значение с плавающей запятой теряет некоторую точность при упаковке и распаковке, но в остальном данные передаются должным образом. Следует иметь в виду, что в зависимости от значения целого числа может быть более эффективным преобразовать его в текст и затем передать вместо использования struct
. Целое число 1
использует один байт, когда он представлен в виде строки, и четыре байта, когда он упакован в структуру.
Смотрите также
- struct – преобразование между строками и другими типами данных.