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的使用