pack和unpack在处理二进制流中比较常用的封包、解包格式
#  按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
pack(fmt, v1, v2, ...) 
# 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
unpack(fmt, string)       
# 计算给定的格式(fmt)占用多少字节的内存
calcsize(fmt)
fmt格式为:
| FORMAT | C TYPE | PYTHON TYPE | STANDARD SIZE | NOTES | 
|---|
    | x | pad byte | no value |  |  | 
  | c | char | string of length 1 | 1 |  | 
  | b | signed char | integer | 1 | (3) | 
  | B | unsigned char | integer | 1 | (3) | 
  | ? | _Bool | bool | 1 | (1) | 
  | h | short | integer | 2 | (3) | 
  | H | unsigned short | integer | 2 | (3) | 
  | i | int | integer | 4 | (3) | 
  | I | unsigned int | integer | 4 | (3) | 
  | l | long | integer | 4 | (3) | 
  | L | unsigned long | integer | 4 | (3) | 
  | q | long long | integer | 8 | (2), (3) | 
  | Q | unsigned long long | integer | 8 | (2), (3) | 
  | f | float | float | 4 | (4) | 
  | d | double | float | 8 | (4) | 
  | s | char[] | string |  |  | 
  | p | char[] | string |  |  | 
  | P | void * | integer |  | (5), (3) | 
格式中的第一个字符来改变对齐方式(字节序).定义如下
| CHARACTER | BYTE ORDER | SIZE | ALIGNMENT | 
|---|
    | @ | native | native | native | 
  | = | native | standard | none | 
  | < | little-endian | standard | none | 
  | > | big-endian | standard | none | 
  | ! | network (= big-endian) | standard | none | 
例如:数据格式为:
  unsigned short  id;
    char[4] tag;
    unsigned int  version;
    unsigned int  count;
解包: 
 import  struct
id, tag, version, count =  struct.unpack("!H4s2I", s)
封包:
 ss =  struct.pack("!H4s2I", id, tag, version, count);
例如:格式为:2字节(包长度)+4字节(包id)+包内容  >表示字节序
  解包
          size, = struct.unpack('>H',raw[0:2])
            cmd, = struct.unpack('>H', raw[2:4])
            string, = struct.unpack('>{0}s'.format(size - 4), raw[4:size])
封包:
        fmt = ">HH{0}s".format(len(result))
        args = (len(result), cmd,result)
        data = struct.pack(fmt, *args)