Десериализация данных C

#python #networking #udp #deserialization

#python #создание сетей #udp #десериализация

Вопрос:

Я получаю структуру по сети от сервера C к моему клиенту Python. Протокол является UDP. У меня нет контроля над сервером и его протоколами / форматами данных. Он состоит из этой структуры (да, порт IPv4 ):

 struct ip_s {
    uint8_t i1;
    uint8_t i2;
    uint8_t i3;
    uint8_t i4;
    uint16_t port; // big endian
};
  

Помимо порта, который преобразуется в формат big-endian, данные отправляются «как есть», преобразуясь в (char*) .

Как я могу получить эту структуру в формате, который обрабатывается Python?


Разная информация:

  • Python 2.7 или 3.x
  • Кроссплатформенный
  • Предпочтительно решение, использующее только встроенные модули

Ответ №1:

Загляните в struct.распакуйте

Вероятно, это будет выглядеть примерно так:

 # socket setup

(buffer, sockaddress) = mysocket.recvfrom(6)
if len(buffer)== 6:
    i1,i2,i3,i4, port = struct.unpack('!BBBBH', buffer)
  

Комментарии:

1. Да, я уже нашел это сразу после запроса, но я оставлю вопрос здесь для дальнейшего ознакомления.

2. О, и "BBBBH" должно было быть "!BBBBH" для порта с большим расширением.

Ответ №2:

Я получаю структуру по сети

Остановитесь прямо на этом. Не делайте этого. Этот метод вводит следующие зависимости:

  1. Порядок слов: в алфавитном порядке или в алфавитном порядке.
  2. Заполнение.
  3. Упаковка.

(2) и (3), в свою очередь, зависят от:

  1. Компилятор.
  2. Версия компилятора.
  3. Окружающие #прагмы.
  4. Параметры компилятора, действовавшие при компиляции программы на C.

Это довольно много зависимостей. Не делайте этого. Определите протокол приложения и используйте его. Или используйте что-то вроде XDR, которое решит проблему за вас.

Комментарии:

1. Возможно, вам не следует «останавливаться прямо там», по крайней мере, не с чтением: I have no control over the server and it's protocols/data formats.

2. @nightcracker Итак, либо сервер спроектирован некомпетентно, и кому-то нужно получить над ним контроль, либо, что более вероятно, это просто способ описания протокола приложения, и на самом деле это проводной протокол, состоящий из четырех октетов, за которыми следует двухоктетное целое число в сетевом порядке байтов.

3. Нет никакой разницы между вашим описанием и моим, потому что реализация использует uint8 и подобные, которые не оставляют места для реализации. Я действительно зациклен на дизайне сервера, это главный сервер для CoD4, основанный на этом коде .