python:基于TCP协议接收数据并解析保存至redis内存库

150 阅读2分钟

python项目:基于TCP协议接收客户端数据并解析保存至redis内存库

完整代码
import socket
# from time import ctime
import struct
import redis
import time

# 连接redis
r = redis.Redis(host='127.0.0.1', port=6379, db=1)
pool = redis.ConnectionPool()
r_pool = redis.Redis(connection_pool=pool)

# 创建服务器
myname = socket.getfqdn(socket.gethostname())
myaddr = socket.gethostbyname(myname)
print(myaddr)
port = 8234
# buffsize = 2048
ADDR = (myaddr, port)

tctime = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tctime.bind(ADDR)
tctime.listen(5)

# 解析TLV结构的数据
def tlv(data):
    i = 1
    while data:
        try:
            type, length = struct.unpack('!HH', data[:4])
            # print(len(data[4:length]))
            # value = struct.unpack('>%dB' % (length - 4), data[4:length])
            if i <= 7:
                value = struct.unpack('>%dH' % int((length-4)/2), data[4:length])
            elif i == 8:
                value = []
                value1 = struct.unpack('>%dB' % len(data[4:length]), data[4:length])
                for j in range(int(len(value1)/3)):
                    value.append(value1[3*j]*16**4 + value1[3*j+1]*16**2 + value1[3*j+2])
                value = tuple(value)

            else:
                value = struct.unpack('>H', data[4:length])
        except:
            print('Unproper TLV structure found: ', (data, ))
            break
        yield type, value
        data = data[length:]
        i += 1

# 根据本地时间创建key名
name = time.strftime("%Y-%m-%d-%H_%M_%S",time.localtime(time.time())) + '_EcgData'

# 创建永久循环接收客户端数据
while True:
    print('Wait for connection ...')
    tctimeClient, addr = tctime.accept()
    print("Connection from :", addr)
    while True:
        header_size = struct.calcsize('>BBHHBB') # 计算帧头长度
        recv_header = tctimeClient.recv(header_size) # 接收数据帧头

        if len(recv_header) != header_size: 
            continue

        header = struct.unpack('>BBHHBB', recv_header) # 解析帧头
        data_size = header[2] - header_size # 计算数据包长度
        recv_data = tctimeClient.recv(data_size) # 接收剩余的数据(TLV结构)

        if len(recv_data) < data_size: # 如果接收的数据少于数据包应有的长度,继续接收
            recv_data += tctimeClient.recv(data_size - len(recv_data))
        # print(len(recv_data))
        # key = ['EcgData%d' % i for i in range(7)]
        # key = key + ['ResData', 'BatData', 'RefData', 'Ref0Data', 'ErrData']
        k = 0
        for type, data in tlv(recv_data): # 迭代输出type值和data
            print(k)
            print(type, data)
            if k <= 6:
                for i in data:
                    r.rpush(name, i) # 创建key值为name的列表,保存至redis内存库
            k += 1
        print(r.lrange(name, 0, -1))

        if not recv_data:
            break
    tctimeClient.close()
tctimeClient.close()

这次小实践中主要接触到了几个技术问题:

python的TCP编程

python操作redis内存库

python做数据解析

python模块struct的使用

测试新人可以学习《测试人的 Python 工具书》书籍《性能测试 JMeter 实战》书籍