Сокеты Python и C ++, конвертирующие пакетные данные - PullRequest
1 голос
/ 14 апреля 2010

Прежде всего, чтобы прояснить мою цель: в нашей лаборатории существуют две программы, написанные на C. Я работаю над прокси-сервером (двунаправленным) для них (который также будет обрабатывать данные). И я хочу написать этот прокси-сервер на Python. Важно знать, что я почти ничего не знаю об этих двух программах, я знаю только файл определения пакетов.

Теперь: при условии, что определение пакета в одной из программ на C ++ выглядит следующим образом:

unsigned char Packet[0x32]; // Packet[Length]
int z=0;

Packet[0]=0x00;     // Spare
Packet[1]=0x32;     // Length
Packet[2]=0x01;     // Source
Packet[3]=0x02;     // Destination
Packet[4]=0x01;     // ID
Packet[5]=0x00;     // Spare
for(z=0;z<=24;z+=8)
{
    Packet[9-z/8]=((int)(720000+armcontrolpacket->dof0_rot*1000)/(int)pow((double)2,(double)z));
    Packet[13-z/8]=((int)(720000+armcontrolpacket->dof0_speed*1000)/(int)pow((double)2,(double)z));
    Packet[17-z/8]=((int)(720000+armcontrolpacket->dof1_rot*1000)/(int)pow((double)2,(double)z));
    Packet[21-z/8]=((int)(720000+armcontrolpacket->dof1_speed*1000)/(int)pow((double)2,(double)z));
    Packet[25-z/8]=((int)(720000+armcontrolpacket->dof2_rot*1000)/(int)pow((double)2,(double)z));
    Packet[29-z/8]=((int)(720000+armcontrolpacket->dof2_speed*1000)/(int)pow((double)2,(double)z));
    Packet[33-z/8]=((int)(720000+armcontrolpacket->dof3_rot*1000)/(int)pow((double)2,(double)z));
    Packet[37-z/8]=((int)(720000+armcontrolpacket->dof3_speed*1000)/(int)pow((double)2,(double)z));
    Packet[41-z/8]=((int)(720000+armcontrolpacket->dof4_rot*1000)/(int)pow((double)2,(double)z));
    Packet[45-z/8]=((int)(720000+armcontrolpacket->dof4_speed*1000)/(int)pow((double)2,(double)z));
    Packet[49-z/8]=((int)armcontrolpacket->timestamp/(int)pow(2.0,(double)z));
}
if(SendPacket(sock,(char*)&Packet,sizeof(Packet)))
    return 1;
return 0;

Какой самый простой способ получить эти данные, преобразовать их в читаемый формат python, управлять ими и отправлять их получателю?

Ответы [ 2 ]

4 голосов
/ 14 апреля 2010

Вы можете получить 50 байтов пакета с помощью вызова .recv на правильно подключенном сокете (в маловероятном случае фрагментации TCP-пакета может потребоваться более одного вызова, поэтому проверяйте входящую длину, пока не получите ровно 50 байтов в руке; -).

После этого, понимание того, что C-код озадачивает. Назначения int с (предположительно по 4 байта каждое) на Packet[9], Packet[13] и т. Д. Создают впечатление, что целью является установка 4 байтов за раз в пределах Packet, но это не то, что происходит: каждое назначение устанавливает ровно один байт в пакете, начиная с младшего байта int, который является RHS назначения. Но эти байты являются байтами (int)(720000+armcontrolpacket->dof0_rot*1000) и так далее ...

Так что, должны ли последние 44 байта пакета интерпретироваться как 11 4-байтовых целых чисел (со знаком «без знака») или 44 независимых значения? Я угадаю первое и сделаю ...:

import struct
f = '>x4bx11i'
values = struct.unpack(f, packet)

формат f указывает: старшие, 4 байта без знака, окруженные двумя игнорируемыми «запасными» байтами, 11 4-байтовыми целыми числами со знаком. Кортеж values заканчивается 15 значениями: четырьмя одиночными байтами (50, 1, 2, 1 в вашем примере), затем 11 целыми числами со знаком. Вы можете использовать ту же строку формата, чтобы упаковать измененную версию кортежа обратно в 50-байтовый пакет для повторной отправки.

Поскольку вы явно указываете длину в пакете, возможно, что разные пакеты имеют разные длины (хотя это несовместимо с объявлением фиксированной длины в вашем образце C), и в этом случае вам нужно быть немного более точным в получении и распаковывать его; однако такие детали зависят от информации, которую вы не предоставляете, поэтому я перестану пытаться угадать; -).

3 голосов
/ 14 апреля 2010

Взгляните на struct module , в частности на функции pack и unpack. Они работают со строками форматирования, которые позволяют вам указать, какие типы вы хотите записать или прочитать и какую последовательность и выравнивание вы хотите использовать.

...