zoukankan      html  css  js  c++  java
  • python中将多个参数打包为字节流进行网络传输的方法

    使用Python写上位机软件时,若通过网口向硬件端发送命令参数对仪器进行控制,此时需要将多个参数打包为字节流数据后进行网络传输,可以使用模块struct和socket完成。

    具体实现代码如下:

     1 # -*- coding: utf-8 -*-#
     2 
     3 #-------------------------------------------------------------------------------
     4 # Name:         发送参数包
     5 # Description:  整个包大小为64Byte,包头为0X”FAA5 FBB5 FCC4 FDD5”,包尾为0X”5FA5 5FB5 5FC5 5FD5 ”,中间不足部分补0
     6 # Author:       lgk
     7 # Date:         2018/6/13
     8 #-------------------------------------------------------------------------------
     9 
    10 import socket
    11 import struct
    12 import ctypes
    13 import binascii
    14 import re
    15 
    16 #字节顺序定义
    17 byteOrders = {'Native order':'@',
    18               'Native standard':'=',
    19               'Little-endian':'<',
    20               'Big-endian':'>',
    21               'Network order':'!'}
    22 
    23 byteOrder = 'Little-endian'
    24 
    25 #发送的参数定义(有符号整型数字)
    26 cmdType = 1         # 1 Byte
    27 sigType = 2         # 1 Byte
    28 startFreq = 40      # 4 Byte
    29 stopFreq = 400      # 4 Byte
    30 deltFreq = 10       # 4 Byte
    31 pulseNum = 37       # 2 Byte
    32 pulseWidth = 0      # 4 Byte
    33 PRF = 25000000      # 4 Byte
    34 receiverFreq = 1000 # 4 Byte
    35 
    36 headInfo = [0xFA, 0xA5, 0xFB, 0xB5, 0xFC, 0xC5, 0xFD, 0xD5]
    37 tailInfo = [0x5F, 0xA5, 0x5F, 0xB5, 0x5F, 0xC5, 0x5F, 0xD5]
    38 
    39 fmt_head = fmt_tail = struct.Struct(byteOrders[byteOrder] + "8B")
    40 fmt_body = struct.Struct(byteOrders[byteOrder] + "2b3i1h3i")
    41 bufferLength = 64
    42 
    43 sendBuffer = ctypes.create_string_buffer(bufferLength) #创建发送缓冲区
    44 
    45 #将待发送的参数打包到缓冲区
    46 fmt_head.pack_into(sendBuffer, 0, *headInfo)
    47 fmt_tail.pack_into(sendBuffer, bufferLength-fmt_tail.size, *tailInfo)
    48 fmt_body.pack_into(sendBuffer, fmt_head.size, cmdType, sigType, startFreq, stopFreq, deltFreq, pulseNum, pulseWidth, PRF, receiverFreq)
    49 
    50 def getSendInfo(info):
    51     # t = ''
    52     # for i in range(len(info) / 2):
    53     #     t += info[2 * i:2 * (i + 1)] + ' '
    54     # t = t.strip().upper()
    55     p = re.compile('.{1,2}') #匹配任意字符1-2次
    56     t = ' '.join(p.findall(info.upper()))
    57     return t
    58 
    59 #打印出字节流的16进制信息
    60 #FA A5 FB B5 FC C5 FD D5 01 02 28 00 00 00 90 01 00 00 0A 00 00 00 25 00 00 00 00 00 40 78 7D 01 E8 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5F A5 5F B5 5F C5 5F D5
    61 print(getSendInfo(binascii.hexlify(sendBuffer)))
    62 
    63 #通过socket发送到服务器端
    64 HOST = '192.168.1.122'
    65 PORT = 8001
    66 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    67 s.connect((HOST, PORT))
    68 s.send(sendBuffer)
    69 s.close()

    其中,struct中支持的格式如下图所示:

    打包的后的字节顺序默认上是由操作系统的决定的,struct模块提供了自定义字节顺序的功能,可以指定大端存储、小端存储等特定的字节顺序,对于底层通信的字节顺序是十分重要,不同的字节顺序和存储方式也会导致字节大小的不同。在format字符串前面加上特定的符号即可以表示不同的字节顺序存储方式,例如采用小端存储 s = struct.Struct(‘<I3sf’)就可以了。其对照列表如下:

  • 相关阅读:
    haproxy教程
    haproxy和keepalived的理解(转载)
    redis集群搭建_超详细
    磁盘IO过高时的参考
    tomcat优化
    MYSQL数据库的主从复制
    k8s学习笔记-etcd介绍和集群搭建
    python排序算法二---冒泡排序
    Python排序算法一—快速排序
    python:如何判断字典a在字典b
  • 原文地址:https://www.cnblogs.com/luke0011/p/9182453.html
Copyright © 2011-2022 走看看