По умолчанию ваш вызов pack
эквивалентен следующему:
struct.pack('@HcHH', port, flags, len(fragments), len(name))
Результат выглядит следующим образом (напечатано '.'.join(f'{x:02X} for x in data')
):
33.05.40.00.04.00.0B.00
0 1 2 3 4 5 6 7
Число 4 закодировано в байтах 4 и 5 в младшем порядке, а 11 закодировано в байтах 6 и 7. Байт 3 является байтом заполнения, вставленным pack
для правильного выравнивания следующего short
s на четной границе.
По документам :
Примечание По умолчанию результат упаковки данной структуры C включаетбайты заполнения для обеспечения правильного выравнивания для задействованных типов Си;аналогично, выравнивание учитывается при распаковке. Это поведение выбрано так, чтобы байты упакованной структуры точно соответствовали расположению в памяти соответствующей структуры Си. Чтобы обрабатывать независимые от платформы форматы данных или опускать неявные байты пэдов, используйте размер и выравнивание standard
вместо размера и выравнивания native
: подробности см. Порядок, размер и выравнивание байтов .
Для удаления байта выравнивания и обоснования ваших предположений о позициях байтов при сохранении собственного порядка байтов используйте
struct.pack('=HcHH', port, flags, len(fragments), len(name))
. Вы также можете использовать фиксированный порядок байтов с помощью <
или>
в качестве префикса.
«Правильное» решение - использовать unpack
, чтобы вернуть свои номера, чтобы вам не приходилось беспокоиться о порядке байтов, заполнении или чем-либо ещеиначе, действительно.