Запись двоичных данных в сокет (или файл) с помощью Python - PullRequest
9 голосов
/ 26 марта 2009

Допустим, у меня есть сокетное соединение, и сторонний слушатель с другой стороны ожидает, что данные будут передаваться очень структурированным образом. Например, он ищет неподписанный байт, который обозначает тип отправляемого сообщения, за которым следует целое число без знака, которое обозначает длину сообщения, затем другой байт без знака, который на самом деле является битовым полем с некоторыми установленными или неустановленными флагами и т. Д. .

Как бы я сделал это в Python? Мне просто интересно, как надежно сгенерировать эти данные и убедиться, что я их отправляю правильно (то есть, что я действительно отправляю неподписанный байт, а не говорю целое число со знаком или, что еще хуже, строка).

Ответы [ 3 ]

11 голосов
/ 26 марта 2009

Используйте модуль struct , чтобы построить буфер и записать его.

4 голосов
/ 26 марта 2009

Очень элегантный способ обработки этих переходов между объектами Python и двоичным представлением (в обоих направлениях) - использование библиотеки Construct .

В их документации вы найдете много хороших примеров его использования. Я сам использую его уже несколько лет для протоколов последовательной связи и декодирования двоичных данных.

0 голосов
/ 26 марта 2009

На самом низком уровне сокет ввода / вывода состоит из чтения или записи строки байтовых значений в сокет. Для этого я кодирую информацию, которая должна быть записана в виде строки символов, содержащей байтовые значения, и записываю ее в сокет. Я делаю это, создавая суперструну, а затем добавляя по одному символу за раз. например, чтобы создать запрос чтения Modbus / Ethernet:

    readRequest = """"""
    readRequest += chr(self.transactionID / 0x100)  # Transaction ID MSB         (0)
    readRequest += chr(self.transactionID % 0x100)  # Transaction ID LSB         (1)
    readRequest += chr(0)                           # Protocol ID MSB (Always 0) (2)
    readRequest += chr(0)                           # Protocol ID LSB (Always 0) (3)
    readRequest += chr(0)                           # Length MSB (Always 0)      (4)
    readRequest += chr(6)                           # Length LSB (Always 6)      (5)
    readRequest += chr(0)                           # Unit ID (Always 0)         (6)

    readRequest += chr(0x04)                        # Function code 4     (0)
    readRequest += chr(startOffset / 0x100)         # Starting offset MSB (1)
    readRequest += chr(startOffset % 0x100)         # Starting offset LSB (2)
    readRequest += chr(0)                           # Word count MSB      (3)
    readRequest += chr(2 * nToRead)                 # Word count LSB      (4)

    sockOutfile.write(readRequest)

Чтобы преобразовать многобайтовые значения в символьные строки, чтобы их можно было добавлять в строку ввода / вывода, используйте функцию «Pack ()» в модуле структуры. Эта функция преобразует одно или несколько одиночных или нескольких байтовых значений в строку отдельных байтовых значений.

Конечно, этот метод примерно так же прост, как молоток. Это необходимо исправить, если кодировка символов по умолчанию в строке - Unicode вместо ASCII.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...