2009-03-26 2 views
9

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

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

ответ

11

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

0

На самом низком уровне разъем ввода-вывода состоит из чтения или записи строки байтовых значений в сокет. Для этого я кодирую информацию, которая должна быть записана в виде строки символов, содержащей байтовые значения, и записывать ее в сокет. Я делаю это, создавая суперструну, а затем добавляю один символ за раз. например, для создания 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) 

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

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

+0

Это не очень хорошая идея. Это склонность к ошибкам и ее трудно поддерживать. Структурный модуль - намного лучший способ сделать это. – Ferruccio

+0

Да, я должен согласиться. К сожалению, я написал это, изучая Python, и написал его так, как будто я все еще писал на C. – mkClark

4

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

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

Смежные вопросы