Почему упакованная длина моих данных не соответствует тому, что было объявлено в структуре?

Я работаю над реализацией bittorrent для своего собственного назидания, но у меня возникают проблемы с упаковкой байтов в пакет рукопожатия. Ниже приведена таблица с подробным описанием характера данных, с которыми я работаю:

Примечание: сообщение рукопожатия следует за формой <pstrlen><pstr><reserved><info_hash><peer_id>

Сообщение о рукопожатии имеет вид <pstrlen> <pstr> <резервированный> <info_hash> <peer_id <резервированный>

Я проверил, что все мои переменные данных имеют ожидаемую длину, но вместо получения упакованной структуры длины 68 ​​я получаю одну из длины 72. Ниже приведен тестовый пример:

from struct import Struct

handshake = Struct('B19sQ20s20s')

pstrlen = 19
pstr = 'BitTorrent protocol'
reserved = 0
info_hash = 'x' * 20
peer_id = 'y' * 20

pkg = handshake.pack(pstrlen, pstr, reserved, info_hash, peer_id)
print len(pkg)

Я явно упускаю что-то очевидное. Что дает?

1 ответ

Решение

Обратите внимание, что struct.calcsize('B19sQ20s20s') возвращает 72; struct.calcsize('<B19sQ20s20s') (как предложено @Joran Beasley) возвращает 68; Я предполагаю, что это проблема выравнивания. Я бы предложил использовать 8B вместо Q для хранения зарезервированных значений

from struct import Struct

handshake = Struct('B19s8B20s20s')

pstrlen = 19
pstr = 'BitTorrent protocol'
info_hash = 'x' * 20
peer_id = 'y' * 20

pkg = handshake.pack(pstrlen, pstr, 0,0,0,0,0,0,0,0, info_hash, peer_id)
print len(pkg)

(Это печатает 68)

Другие вопросы по тегам