Как разобрать двоичные данные из сокета в python?

В настоящее время я работаю над проектом, в котором мне нужно связаться с микрожестким сотовым модемом IPn3G. У меня настроен модем для отправки сообщений на мой компьютер через TCP, и я могу получить сообщение в сокете.

Однако сообщение выглядит так:

���������DKReadyCANRogersWirelessInc. Home354626030393530302720391029547

Теперь я могу распознать некоторые из этих полей, таких как статус или информация о перевозчике, а также imei и imsi в конце.

Моя проблема в том, как мне разобрать забавно выглядящие вещи? Я пробовал struct, но мне это не очень помогло.

В документации модема нашел только это:

Структура сообщения Modem_event:

  • фиксированный заголовок (фиксированный размер 20 байт)
  • Идентификатор модема (uint64_t (8 байт))
  • Маска типа сообщения (uint8_t(1 байт))
  • сдержанный
  • длина пакета (uint16_t(2 байта)) Примечание: длина пакета = длина фиксированного заголовка + длина полезной нагрузки сообщения.

Информация о перевозчике:

  • Длина содержимого 2 БАЙТА (UINT16_T)
  • RSSI 1 БАЙТ (UINT8_T)
  • РЧ-диапазон 2 БАЙТА (UINT16_T)
  • Тип службы STRING (1–30 байт)
  • Номер канала STRING (1–30 байт)
  • Номер SIM-карты STRING (1–30 байт)
  • Номер телефона STRING (1–30 байт)

Мне кажется, что сообщение даже не соответствует тому, что должно быть. Буду очень рад, если кто-нибудь подскажет, как решить эту проблему.

Спасибо


person masterlampe    schedule 27.04.2012    source источник
comment
Как выглядит сообщение, например. при печати на консоль не очень полезно. В частности, маловероятно появление каких-либо байтов NUL ('\x00'). Вместо print message сделайте print repr(message)   -  person John Machin    schedule 28.04.2012
comment
Показывает ли документация, как долго зарезервировано? Что вы имеете в виду под словами «я могу распознать некоторые из этих полей, таких как статус или информация о перевозчике»? Что такое статус? Что должно быть в фиксированном заголовке?   -  person John Machin    schedule 28.04.2012
comment
@JohnMachin: новый вывод с repr(message): \xb7\xff\xff\xff\xff\xff\xff\xff\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00D \x00\xf3\x00\x00Готово\x00CANRogersWirelessInc.\x00Home\x00354626030393530\x00302720391029547\x00.   -  person masterlampe    schedule 28.04.2012
comment
Также в документации не указано, как долго зарезервировано или что находится в фиксированном заголовке. Я узнаю несколько полей, таких как Status=Ready, Carrier=CANRogersWirelessInc., Home=Home, IMEI=354626030393530 и IMSI=302720391029547. Но на самом деле их не должно быть в выводе, поэтому я не знаю, является ли это частью заголовка.   -  person masterlampe    schedule 28.04.2012
comment
Сообщение, которое вы показываете, имеет только 25 байтов перед строками переменной длины, начинающимися с Ready. Как вы говорите, это не совпадает ни с одним из двух фрагментов документации. У вас проблемы с документацией, и мы не можем вам с этим помочь. Конечно, это устройство должно использовать для связи какой-то международный стандартный протокол...   -  person John Machin    schedule 29.04.2012
comment
Ладно, я тоже об этом подумал. Я надеюсь получить ответ от службы поддержки microhard, который поможет мне понять сообщение. Ну все равно спасибо за помощь.   -  person masterlampe    schedule 29.04.2012


Ответы (1)


В Python есть отличный модуль struct, который позволяет упаковывать и распаковывать двоичные данные.

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

Получите размер строковой части сообщения (из размера других полей и длины пакета) и прочитайте все строки в одну строку Python, используя <number>s, и разделите их, найдя нулевые символы.

person Rafał Rawicki    schedule 27.04.2012