Конвертировать из python struct.pack (big-endian) в список целых чисел - PullRequest
0 голосов
/ 12 ноября 2018

* РЕДАКТИРОВАТЬ: Название неверно, Big-Endian должен быть Little-Endian. Не хотел меняться из-за предоставленных решений.

Я пытаюсь преобразовать строку (например, b '\ x01 \ x00 \ x00 \ x00' <- 32-битное целое число) обратно в целое число в моей программе на Си. </p>

Клиент (в Python):

example = [1,2,3]
struct.pack('i'*int(len(example)/4),packed)
<Send over open socket to server>

Сервер (в C):

char buffer[1024];
numbytes = recv(sockfd,buffer,1023,0);
char message[numbytes];
memcpy(message,buffer,n);
<If 'message' is sent back, I can unpack on client>
??? How to unpack on C then repack to send response to client ???

В C я хочу «распаковать» в массив / структуру

Спасибо!

1 Ответ

0 голосов
/ 12 ноября 2018

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

На основании значения b'\x01\x00\x00\x00' кажется более вероятным, что вы кодируете значения в порядке с прямым порядком байтов, и это фактически то, что показал показанный вами вызов struct.pack, если вы его запустите порядковый номер машины Ваш клиент и сервер, вероятно, работают на оборудовании с прямым порядком байтов (хотя вы не указываете это, поэтому невозможно быть уверенным на 100%).

В любом случае, какую бы форму вы ни использовали, вам нужно использовать одинаковые порядковые номера с обеих сторон. Вероятно, лучше не указывать порядок байтов в проводном протоколе, поэтому вам следует убедиться, что и клиент, и сервер преобразуют байты в общий порядок байтов и из него. В стандартах Интернета в качестве стандарта для сетевых протоколов указан big-endian.

Если вы решили стандартизировать данные с прямым порядком байтов, вот что вам нужно сделать:

  • Измените ваш вызов struct.pack, чтобы выбрать кодировку целых чисел с прямым порядком байтов. Вы можете сделать это, добавив префикс '>' к определению структуры.
  • Измените код C так, чтобы он читал каждое целое число по одному (четыре байта для 32-разрядного значения), а затем передал значения через ntohl, чтобы получить uint32_t.
  • Соберите целые числа в свою структуру на стороне сервера.
...