C语言与Python平台通过socket建立结构型方式数据传输通信(使用struct.pack())

解决的问题:1)Python与C跨平台通信(结构型数据传输方式)
2)接收端无故多出0x00字节

TCP/IP协议下,主要有两种通信方式:
1、字符流:字符串形式,没有平台不一致问题,但传输的数据不定长,复合数据类型(如struct)的解析不方便;
2、结构型:按数据类型传输,保证数据长度固定/可控,方便对接受到数据的解析;但前提是要考虑平台不一致问题,如字节序、对齐位宽、数据类型等。

本文采用Python平台编写上位机,C编写下位机,并且按照结构型传输数据,为了将数据转化成在内存中的二进制串结构体数据(C中所用的结构体数据)以供下位机接收,可以用到struct.pack()struct.unpack()
使用方式示例:

##在2i1d1B1B1B1B前加上!,防止int与double数据交界处为了对齐而自动补上的一个四字节的0,同时会改变大小端

import struct
import string
def main():
    data_int1 = 256
    data_int2 = 122
    data_float = 120.04
    data_float2 = 30.23
    data_head1 = 0xff
    data_head2 = 0xff
    data_head3 = 0xff
    data_head4 = 0xff
    '''
    如果按网络传输接收到字符串,可在2i1d1B1B1B1B前加上!,改为!2i1d1B1B1B1B,会改变大小端
    上位机通过socket.recv接收到了一个c语言编写的下位机的结构体数据,存在字符串dataTobytes中
    a, b, c , d, e, f, g= struct.unpack('!2i1d1B1B1B1B', dataTobytes),
    2i表示对应于c语言2个4字节int类型数据
    1d表示对应于c语言1个8字节double类型数据
    1B表示对应于c语言一个字节无符号char
    '''
    dataTobytes = struct.pack('2i2d1B1B1B1B', data_int1, data_int2, data_float,data_float2, data_head1,data_head2, data_head3, data_head4  )
    print(type(dataTobytes[0:4]), len(dataTobytes))
    # print(dataTobytes[0])
    # print(dataTobytes[1])
    # print(dataTobytes[2])
    # print(dataTobytes[3])
    # print(dataTobytes[4])
    '''
    dataTobytes为字符串,对应于data_int1, data_int2, data_float, data_head1,data_head2, data_head3, data_head4在内存中的二进制串
    如,前四个字节传送的是data_int1,则前面四个字符为0x00,0x01,0x00,0x00
    '''
    #dataTobytes = struct.pack('2i1d', data_int1, data_int2, data_float )
    a, b, c , d, e, f, g,h= struct.unpack('2i2d1B1B1B1B', dataTobytes)
    # a, b, c = struct.unpack('2i1d', dataTobytes)
    # print(a)
    # print(b)
    # print(c)
    # print(d)
    # print(e)
    # print(f)
    # print(g)

    # 打印浮点数120.04和30.23的二进制串
    for i in range(8,24):
        print(dataTobytes[i])
if __name__ == "__main__":
    main()

之后用send向下位机发送dataTobytes即可:

server.send(dataTobytes)

Note: 有时候为了对齐,不同类型数据交接处系统会补充0(也就是无故多出0x00字节),此时要在2i2d1B1B1B1B前加上”!”(会修改为大端模式对齐)。
1.网络数据(socket)传输总结见:
https://blog.csdn.net/wangzuojoe/article/details/5163102
2.struct.pack()和struct.unpack()用法详解见:
https://blog.csdn.net/weiwangchao_/article/details/80395941?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160099634819195188313115%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=160099634819195188313115&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v2-2-80395941.first_rank_ecpm_v3_pc_rank_v2&utm_term=struct.pack&spm=1018.2118.3001.4187

3.大端小端(高低位字节)详解见:
https://blog.csdn.net/aigoV/article/details/78706609?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160099674719725271749622%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=160099674719725271749622&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v2-1-78706609.first_rank_ecpm_v3_pc_rank_v2&utm_term=%E9%AB%98%E4%BD%8D%E4%BD%8E%E4%BD%8D&spm=1018.2118.3001.4187

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值