前言
关于项目函数的一些知识可以在前面的文章中学习。
【Python】发送udp数据(保姆级图文+附测试工具文件+api例程)
【Python】接收UDP数据(保姆级图文+附测试工具文件+api例程)
项目要求
程序中监听网关发送给本机的UDP数据包,端口号默认为10352,可以修改。启动程序后就开始监听数据并进行解析,解析200条数据后停止程序,得到的数据保存到文件中,文件名为 YYYY-MM-DD(年月日)-HH-MM-SS(时分秒)命名, 格式最好为excel能打开的xls格式。 例如文件名为 “2021-12-02-10-03-23. xls”.
文件存放的每条数据包括三部分 :
标签MAC地址(6个字节,直接取自UDP数据包格式不变):data[8:14] ‘51’, ‘00’, ‘00’, ‘89’, ‘60’, ‘c2’,
方位角(10进制):data[16]-data[15] ‘3f’-‘00’
俯仰角(10进制):data[18]-data[17] ‘30’-‘00’
发送的单条数据:
8E 10 02 00 90 BE 0C 01 51 00 00 89 60 C2 00 00 3F 00 30 11 28 7D 8D
解析后的单条数据:
5100009060C2 210 13
发送时的数据图片:
工具下载百度链接:https://pan.baidu.com/s/19pzqqUczM7cTxbGJvPwEDA
提取码:1hs6
解析后生成的xls文件:
接收数据流程:
- 接收数据
- 处理数据
- 保存文件
# @Time : 2021/12/9 14:27
# @Author : 南黎
# @FileName: 解析数据2.0.py
############################获取udp数据############################
import socket
def getDate():
# 1.创建一个udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配
# 30000 表示本地的端口 ip一般不用写
local_addr = ("", 60826)
udp_socket.bind(local_addr)
# 3. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024)
# 1024表示本次接收的最大字节数
# 4. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
# print(recv_data)#输出接收到的原始数据数据是一个元组(b'\x8e\x10\x02\x00\x90\xbe\x0c\x01Q\x00\x00\x89`\xc2\x00\x00?\x000\x11(}\x8d', ('127.0.0.1', 10360))
#注意如果发送和解码方式不一样会报错!()type类型都是bytes,但是一个是asc一个是hex解码方式不同)
# 2个思路我2小时没找到实现方法:1.判断编码方式结合if和else;2.用异常处理解决。因为时间紧,没时间研究了,大家集思广益一下
# 因为博主我的项目只用于hex所以我就注释了asc,大家如果用asc可以注释掉hex
#1.如果是Hex发送, 解码得到8e10020090be0c015100008960c200003f003011287d8d
result_recv_data=recv_data[0].hex()
#2.如果是ASCII发送,解码得到8E 10 02 00 90 BE 0C 01 51 00 00 89 60 C2 00 00 3F 00 30 11 28 7D 8D
# result_recv_data = recv_data[0].decode('utf-8')
# print(result_recv_data)#输出解码后的数据
# 3.关闭套接字
udp_socket.close()
# 把8e10020090be0c015100008960c200003f003011287d8d转化为
# ['8e', '10', '02', '00', '90', 'be', '0c', '01', '51', '00', '00', '89', '60', 'c2', '00', '00', '3f', '00', '30', '11', '28', '7d', '8d']
ls = []
for i in range(len(result_recv_data) // 2):
ls.append(result_recv_data[i * 2] + result_recv_data[i * 2 + 1])
return ls
############################处理得到的udp数据############################
import numpy as np
import pandas as pd
import time
# 功能说明:输入一个16进制数,转化为10进制数 16进制->10进制
# 返回值:int的16进制转化后的10进制数据
def style16to10(x):
return int(x, 16)
# 功能说明:获取文件名称的函数 根据获取的当前时间确定格式化的文件名
# 返回值:str的文件名
def get_data_name():
data_time=time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime())#格式化获取的当地时间
data_name=data_time+".xls"
return data_name
############################主函数############################
# date_count=20
date_count=eval(input("项目需要20条记录,也可以手动输入"))#项目需要20条记录,也可以手动输入
date_ls=[]#存储记录的np数组
print("开始获取UDP数据")
for i in range(date_count):
date_ls.append(getDate())#获取UDP数据,放入列表
# print(date_ls)#输出得到的二维列表组
save_data=[]
for i in range(len(date_ls)): #遍历每一行数据
mac_address="".join(date_ls[i][8:14])
heading=style16to10(date_ls[i][16])-style16to10(date_ls[i][15]) #方位角
tilt=style16to10(date_ls[i][18])-style16to10(date_ls[i][17]) #俯仰角
# print([mac_address,str(heading),str(tilt)])#测试每一行要被保存的最终数据结果
save_data.append([str(mac_address),str(heading),str(tilt)])
pd.DataFrame(save_data,index=[x for x in range(date_count)],columns=['标签MAC','方位角','俯仰角']).to_excel(get_data_name())
print(get_data_name()+"保存成功!")
注意事项
- 这里为了显示接收到的数据,进行了解码处理。
- 如果是hex模式发送数据,使用hex解码方式得到的数据是,这些数据还要进一步的处理。
8e10020090be0c015100008960c200003f003011287d8d
ls = []
for i in range(len(result_recv_data) // 2):
ls.append(result_recv_data[i * 2] + result_recv_data[i * 2 + 1])
return ls
才会得到8E 10 02 00 90 BE 0C 01 51 00 00 89 60 C2 00 00 3F 00 30 11 28 7D 8D
- 如果是asc码模式发送数据,使用
.decode('utf-8')
解码得到的数据是8E 10 02 00 90 BE 0C 01 51 00 00 89 60 C2 00 00 3F 00 30 11 28 7D 8D
总结
大家喜欢的话,给个👍,点个关注!继续跟大家分享敲代码过程中遇到的问题!
版权声明:
发现你走远了@mzh原创作品,转载必须标注原文链接
Copyright 2021 mzh
Crated:2021-12-10
欢迎关注 『Python』 系列,持续更新中
欢迎关注 『Python』 系列,持续更新中
【Python安装第三方库一行命令永久提高速度】
【使用PyInstaller打包Python文件】
【Python】发送udp数据(保姆级图文+附测试工具文件+api例程)
【Python】接收UDP数据(保姆级图文+附测试工具文件+api例程)
【更多内容敬请期待】