Q:

Why doesn't the packed length of my data correspond to what was declared in the struct?

I'm working on a bittorrent implementation for my own edification, but I'm having a bit of trouble packing bytes into a handshake packet.  Below is a table detailing the nature of the data I'm working with:
Note:  Handshake message follows the form <pstrlen><pstr><reserved><info_hash><peer_id>

I've verified that all my data variables have the expected length, but instead of getting a packed struct of length 68, I get one of length 72.  Below is a test case:
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)

I'm clearly missing something obvious.  What gives?

A:

Note that struct.calcsize('B19sQ20s20s') returns 72; struct.calcsize('<B19sQ20s20s') (as suggested by @Joran Beasley) returns 68; I'm assuming this is an alignment issue.  I'd suggest using 8B instead of Q to hold the reserved values
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)

(This prints out 68)

