• Python与C++结构体交互


    需求:根据接口规范,实现与服务端的数据交互

    服务端结构体分包头、包体、包尾

    包头C++结构体示例如下

     1 typedef struct head
     2 {
     3     BYTE string1;
     4     BYTE    string2;    //包类型
     5     BYTE    string3;            //版本号,目前为0
     6     char    string4[33];        
     7     int        string5;        
     8     int        string6;            
     9     unsigned int string7;    //包头校验和,以上所有字段的crc32校验和
    10     char    string8;
    11     char    string9;
    12 }protocol_head;
    View Code

    包体C++结构体示例如下

    1 typedef struct body
    2 {
    3     char    sessid[33];
    4     int        datalen;    
    5     BYTE    data[0];    
    6 };
    View Code

    包尾C++结构体示例如下

    1 // 包尾 - 粘包分割
    2 typedef struct tag_protocol_tail
    3 {
    4     BYTE tail[4]
    5 }protocol_tail;
    View Code

    根据包头结构体的要求,需要使用CRC32校验

     1 unsigned int GetCRC32(const unsigned char *pbData, int nSize)
     2 {
     3     unsigned long Table[256]={0};
     4     unsigned long  ulPolynomial = 0xEDB88320;
     5 
     6     unsigned long  dwCrc;
     7     int i,j;
     8     for(i = 0; i < 256; i++)
     9     {
    10         dwCrc = i;
    11         for(j = 8; j > 0; j--)
    12         {
    13             if(dwCrc & 1)
    14                 dwCrc = (dwCrc >> 1) ^ ulPolynomial;
    15             else
    16                 dwCrc >>= 1;
    17         }
    18         Table[i] = dwCrc;
    19     }
    20 
    21     unsigned long dwCrc32 = 0xFFFFFFFF;
    22     int idx=0;
    23     while(nSize--)
    24     {
    25         dwCrc32 = ((dwCrc32) >> 8) ^ Table[(pbData[idx]) ^ ((dwCrc32) & 0x000000FF)];
    26         idx++;
    27     }
    28     return ~dw
    View Code

    python 实现内容

    struct中支持的格式如下表:

    Format

    C Type

    Python

    字节数

    x

    pad byte

    no value

    1

    c

    char

    string of length 1

    1

    b

    signed char

    integer

    1

    B

    unsigned char

    integer

    1

    ?

    _Bool

    bool

    1

    h

    short

    integer

    2

    H

    unsigned short

    integer

    2

    i

    int

    integer

    4

    I

    unsigned int

    integer or long

    4

    l

    long

    integer

    4

    L

    unsigned long

    long

    4

    q

    long long

    long

    8

    Q

    unsigned long long

    long

    8

    f

    float

    float

    4

    d

    double

    float

    8

    s

    char[]

    string

    1

    p

    char[]

    string

    1

    P

    void *

    long

     

     举例C中常用:

    int16=short  --> h
    uint32=unsigned int  --> I

    UInt64=unsigned long long --> Q
    byte表示一个字节,对应C的unsigned char  --> B

    python中CRC32校验

     1 def mycrc32(szString):
     2     # 校验码
     3     m_pdwCrc32Table = [0 for x in range(0, 256)]
     4     dwPolynomial = 0xEDB88320
     5     dwCrc = 0
     6     for i in range(0, 255):
     7         dwCrc = i
     8         for j in [8, 7, 6, 5, 4, 3, 2, 1]:
     9             if dwCrc & 1:
    10                 dwCrc = (dwCrc >> 1) ^ dwPolynomial
    11             else:
    12                 dwCrc >>= 1
    13         m_pdwCrc32Table[i] = dwCrc
    14     dwCrc32 = 0xFFFFFFFFL
    15     for i in szString:
    16         b = ord(i)
    17         dwCrc32 = ((dwCrc32) >> 8) ^ m_pdwCrc32Table[(b) ^ ((dwCrc32) & 0x000000FF)]
    18     dwCrc32 = dwCrc32 ^ 0xFFFFFFFFL
    19     return dwCrc32
    View Code

    C++和python关于CRC32代码传入参数如何理解?

    根据上面C++代码内容,可以看到传入2位参数,它的第一位参数是整个包头+包体+包尾内容,第二位参数是整个包前多少位的长度需要校验

    对于python代码,实际上只要传入需要校验的内容。

    本文中需要传入的内容实际上是包头的的前6个字段,也就是包头的string1+string2+string3+string4+string5+string6

    包头代码

     1 # 包头, data为传入的包体,body_len是包体长度
     2 def qzj_head(data, body_len):
     3     string1 = 100
     4     string2 = 1
     5     string3 = 0
     6     string4 = "6"
     7     string5 = body_len
     8     string6 = body_len
     9 
    10     string1 = struct.pack('B', string1 )
    11     string2 = struct.pack('B', string2 )
    12     string3 = struct.pack('B', string3)
    13     string4 = struct.pack('33s', string4 )
    14     string5 = struct.pack('i', string5 )
    15     string6 = struct.pack('i', string6 )
    16 
    17     string7_struct = string1+string2+string3+string4+string5+string6  # 前面的6个字段内容
    18     string7_crc32 = des_key.mycrc32(headcrc_str)  # crc32校验
    19     string7 = struct.pack('I', string7_crc32)
    20     string8 = 0
    21     string9 = 0
    22     string8 = struct.pack('B', string8)
    23     string9 = struct.pack('B', string9)
    24 
    25     request_head = string1+string2+string3+string4+string5+string6+string7+string8+string9+data
    26     return request_head
    View Code

    包尾代码

     1 # 包尾,data是传入的包头+包体
     2 def qzj_tail(data):
     3     tail1 = ''
     4     tail2 = ''
     5     tail3 = '
    '
     6     tail4 = '
    '
     7     tail1 = struct.pack('s', tail1)
     8     tail2 = struct.pack('s', tail2)
     9     tail3 = struct.pack('s', tail3)
    10     tail4 = struct.pack('s', tail4)
    11     request_tail = data+tail1+tail2+tail3+tail4
    12     return request_tail
    View Code

    包体代码

     1 # 包体, data是要发送的json数据
     2 def body_100(data):
     3     string1 = ''
     4     string2 = len(data)
     5     string3 = data
     6 
     7     string1 = struct.pack('33s', string1)
     8     string2 = struct.pack('i', string2)
     9     string3 = struct.pack('%ds' % datalen_num, string3)
    10     request_body = string1+string2+string3
    11     return request_body, len(request_body)
    View Code
  • 相关阅读:
    Prototype源码浅析——Object部分(一)
    JS构建页面的DOM节点结构(二)
    Prototype源码浅析——Object部分(二)之类型检测
    createElement与createDocumentFragment的点点区别
    Prototype源码浅析——Function.prototype部分(二)
    CSS3月食
    javascript管中窥豹——形参与实参
    JS获取整个页面的文档
    2012年总结
    Windows下Android环境搭建(最新最方便)
  • 原文地址:https://www.cnblogs.com/shhnwangjian/p/5147271.html
Copyright © 2020-2023  润新知