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’)就可以了。其对照列表如下:

posted on 2018-06-14 12:09  lgk  阅读(3148)  评论(0编辑  收藏  举报

导航