TCP/IP协议,TCP与平台通信,通讯协议压力测试(python)
最近的项目来了一个需求,要求测试tcp网关通讯协议;
1、液压井盖通过TCP/IP TCP与平台通信;
2、硬件定期发送心跳包(10S)给平台,是平台与硬件保持长连接;
3、每台硬件有一个12字节的唯一编码(字符型);
4、每台设备是1S发送一条报文;
最初使用NetAssist测试功能,模拟硬件设备发送报文,测试硬件设备发过来的状态。
功能测试通过后,新来的压测需求:要求对模拟60个左右的设备每隔一秒发送一条报文到平台,去百度Google搜索TCP压测怎么压测,这类文章博客比较少,试了有个博客自己写的一个软件,发现不能满足需求(都不能安装),其余就是jmeter进行压测,所以就尝试用jmeter进行测试,版本是3.2,按照博客所写进行操作,发现还是不能满足需求,并不能进行60个设备同时1S发送一条报文(加入定时器也不能满足),单个的模拟一个设备可以发送成功。
由于使用工具不能满足需求,只能依靠手写代码来实现了。
common.py 存放公用方法,如进制转化、异或运算等;
manholecover_state.py 结合数据组装报文;
run_test.py 主方法,发送报文,执行脚本;
test.log 日志文件
common.py
# coding=utf8
# import mysql.connector
import binascii # 报文头
def reverseStart_field():
return "F5F5" # 返回序列
def reverseNumber_field():
return "" # 补全字节
def zfill(str1, i):
str1 = str1.zfill(2 * i) # 补全 字节
return str1 # int转16进制
def intChange16(str1, i):
str1 = hex(int(str1)) # 转16进制
str1 = str1.replace("0x", "") # 去掉16进制0x
str1 = str1.zfill(2 * i) # 补全 字节
return str1 # 16进制 去掉0x 补全 字节
def strReplace(str1, i):
str1 = str1.replace("0x", "") # 去掉16进制0x
str1 = str1.zfill(2 * i) # 补全 字节
return str1 # int转16进制 倒序
def change16Reverse(str1, i):
# print("==========调用方法change16Reverse")
str1 = hex(int(str1)) # 转16进制
str1 = str1.replace("0x", "") # 去掉16进制0x
str1 = str1.zfill(2 * i) # 补全 字节
# print("==========倒序之前:",str1)
i = len(str1)
str2 = ""
while (i > 0):
str2 = str2 + (str1[i - 2:i])
i = i - 2
# print("==========倒序之后:",str2)
return str2 # 时间转16进制
def timeChange16(str1):
arrTime = []
arrTime = str1.split('-')
arrChange = []
strChange = ""
i = 0
while (i < len(arrTime)):
if (i == 0):
print("----------")
strChange = change16Reverse(arrTime[i], 2)
else:
strTem2 = intChange16(arrTime[i], 1)
strChange = strChange + strTem2
i = i + 1
return strChange + "FF" # 字符串 转换
def changestr(str2):
length = len(str2)
utf8_length = len(str2.encode('utf-8')) # gbk 8.5 utf-8 9
length = int((utf8_length - length) / 2 + length)
str2 = binascii.b2a_hex(str2.encode("gbk")) # encode("gbk") utf8
str2 = str(str2) # 将 byte 类型转换成 str 类型
str2 = str2.replace("b'", "").replace("'", "") # 去掉 b'
str2 = str2.zfill(2 * length)
return str2 # asc 转换 def changeascii(str1, aa):
e = 0 # 暂存结果
for i in str1:
d = ord(i) # 单个字符转换成ASCii码
e = e * 256 + d # 将单个字符转换成的ASCii码相连
a = hex(e)
a = a.replace("0x", "")
a = a.zfill(2 * aa)
# print("结果是:%s" % a)
return a if __name__ == "__main__":
message_id = '0x10'
case_id = ""
manholecover_state.py
# -*-coding:utf-8-*- # coding=utf8
import mysql.connector
import common
import logging
import datetime
import pymysql def parseadd(case):
config = {
'host': '127.0.0.1', # 连接的IP地址
'user': 'root',
'password': '',
'port': 3306,
'database': 'monitor',
'charset': 'utf8', # 编码格式,防止查出来的数据中文乱码
}
#db1_cursor = mysql.connector.Connect(**config) # 连接数据库
db1_cursor = pymysql.Connect(**config) cur = db1_cursor.cursor() # 执行命令,接收结果
t_str = "select * from monitor.test_manholecover_state_copy where case_id="
try:
cur.execute(t_str + str(case))
t_result = cur.fetchone()
print(t_result)
db1_cursor.close()
print("-----------------------井盖监控点编码", t_result[5])
strElement0 = common.reverseStart_field() # 头
strElement1 = common.reverseNumber_field() # 序列
strElement2 = common.intChange16(t_result[4], 1) # 应答标志
# strElement3=common.changeascii(t_result[5],12)#设备编码
strElement3 = common.changeascii(t_result[5], 12) # 设备编码
logging.info("报文发送时间:" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " 编码:" + t_result[5])
strElement4 = common.intChange16(t_result[6], 1) # 井盖状态
strElement5 = common.intChange16(t_result[7], 1) # 正在操作方式
strElement6 = common.intChange16(t_result[8], 3) # 告警状态
strElement6_1 = common.intChange16(t_result[9], 3) # 告警状态
strElement7 = common.intChange16(t_result[10], 1) # 控制授权
strElement8 = common.intChange16(t_result[11], 1) # 角度状态
strElement9 = common.zfill(t_result[12], 4) # 结束标记 # 拼接字符串
strElement = [strElement0, strElement1, strElement2, strElement3, strElement4, strElement5, strElement6,
strElement6_1, strElement7, strElement8, strElement9]
strResult = ''.join(strElement) # print("=====================")
print("拼接报文:", strResult)
return strResult except Exception as e:
print("Error: %s" % e) if __name__ == "__main__": for id in range(1, 68):
print(parseadd(1)) # db1_cursor = mysql.connector.connect(host='127.0.0.1', port='3306', user='root', password='123456', database='monitor', charset='utf8')
# cur = db1_cursor.cursor()
# case_id='1'
# #parseadd(case_id)
# db1_cursor.close()
run_test.py
# coding=utf-8
import datetime
import logging
import threading
from socket import *
from time import sleep
import manholecover_state # import logging.handlers logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='test.log',
filemode='w')
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
socks = [] def singlesend(case, soc2):
global lock
lock.acquire()
# case_id = 1
# while case_id<=2: #循环次数
print("报文发送时间:" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
print("-----------------------井盖监控点编码", case) # , "上报次数:", case_id)
send_manholecover_state = manholecover_state.parseadd(case)
#print("----------------------", send_manholecover_state + '\n') soc2.send(bytes().fromhex(send_manholecover_state)) # case_id = case_id + 1
# print("报文发送时间:" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# sleep(1) #可修改的上报时间间隔
lock.release() def message():
global lock
lock.acquire()
t_code = 201820190601
threads = []
# while (t_code <= 201820190667):
for case in range(1, 68):
t_singlesend = threading.Thread(target=singlesend, args=(str(case), socks[case-1]))
threads.append(t_singlesend)
# t_singlesend.setDaemon(True)
# t_singlesend.start()
# sleep(1)
t_code += 1 for i in threads:
i.setDaemon(True)
i.start()
lock.release() if __name__ == '__main__':
lock = threading.Lock() end = datetime.datetime.now() + datetime.timedelta(days=2) # 获取结束时间
print("报文发送一周结束时间" + end.strftime("%Y-%m-%d %H:%M:%S") + '\n')
for case in range(1, 68):
soc = socket(AF_INET, SOCK_STREAM)
soc.settimeout(300) # 设置超时时间
soc.connect(('192.168.0.156', 8845))
socks.append(soc) while True:
message()
now = datetime.datetime.now()
sleep(1)
if now >= end:
break '''
threads = []
threads.append(t_singlesend)
for t in threads:
t.start()
for t in threads:
t.join()
logging.info("全部执行完成~:%s" % ctime())
'''
运行结果:达到需求,每秒发送67条报文到平台
在这种正常场景下进行压测,连续跑了几个小时候,平台就崩掉了,java内存不断的升高;
开发进行不断的性能优化,已经连续跑了三四的情况下,平台已经走向稳定。
TCP/IP协议,TCP与平台通信,通讯协议压力测试(python)的更多相关文章
- TCP/IP 中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议
原文地址:http://hi.baidu.com/albyuyrgqgbbhoq/item/65006d2d002ab33195f62ba1 TCP/IP(Transmission Control P ...
- TCP/IP、TCP、UDP、Socket知识汇总
带你了解TCP/IP,UDP,Socket之间关系 https://blog.csdn.net/chaoshenzhaoxichao/article/details/79785318 主要知识点: T ...
- Android之从TCP/IP、HTTP看Socket通信
1.概念 TCP/IP:属于传输层/网络层协议.手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传 ...
- TCP/IP学习笔记1--概述,分组交换协议
1.TCP/IP 互联网是由许多独立发展的网络通信技术融合而成的,能够使它们不断融合并实现统一的正式TCP/IP技术,TCP/IP使通信协议的统称. TCP/IP协议模型(Transmission C ...
- TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
1.IMCP协议介绍 前面讲到了,IP协议并不是一个可靠的协议,它不保证数据被送达,那么,自然的,保证数据送达的工作应该由其他的模块来完成.其中一个重要的模块就是ICMP(网络控制报文)协议. 当传送 ...
- TCP/IP模型各个层次的功能和协议
层次名称 功 能 协 议 应用层 (Application Layer) 负责实现一切与应用程序相关的功能,对应OSI参考模型的上三层 FTP(文件传输协议) HTTP(超文本传输协议 ...
- TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute【转】
转自:http://blog.csdn.net/goodboy1881/article/details/670761 1.IMCP协议介绍 前面讲到了,IP协议并不是一个可靠的协议(是一种尽力传送的协 ...
- <再看TCP/IP第一卷>TCP/IP协议族中的最压轴戏----TCP协议及细节
题外话:刚刚过去的半个月实在是忙得我喘不过来气,虽然手里还压着几个项目得在期末考试之前做完,但是想想还是更新一下随笔,稍微换个心情.另外小吐槽一下那些在博客园里原封不动抄书当随笔的人,唉真是....算 ...
- [TCP/IP] 学习TCP/IP协议的笔记
1.我看的视频是https://www.bilibili.com/video/av10610680?from=search&seid=1733008388243131444这位大大的视频讲解. ...
- TCP/IP和OSI4层、7层协议介绍
1.TCP/IP全称:Transmission Control Protocol / Internet Protocol 中文翻译:传输控制协议 / 互联网协议 2.OSI4层.7层模型:
随机推荐
- exe4j打包--exe转安装包
前面一篇已经详细的说明了打包成exe的步骤了,下面谈谈exe如何压缩成安装文件.这里用到之前的另外一个软件,具体软件看这篇文章 exe4j打包成exe 打开inno 编辑器 打开软件后我们选择 用[脚 ...
- Android删除指定路径下指定前缀或后缀的文件
微信公众号:CodingAndroid CSDN:http://blog.csdn.net/xinpengfei521声明:本文由CodingAndroid原创,未经授权,不可随意转载! 需求 我们在 ...
- 循环while和for
1.循环语句的基本操作 #while循环使用,其中break是用来结束当前循环的 count = 0 while True: print(count) count += 1 if count == 3 ...
- 记一次Linux修改MySQL配置不生效的问题
背景 自己手上有一个项目服务用的是AWS EC2,最近从安全性和性能方面考虑,最近打算把腾讯云的MySQL数据库迁移到AWS RDS上,因为AWS的出口规则和安全组等问题,我需要修改默认的3306端口 ...
- Nacos(一):Nacos介绍
前言 6月份阿里开源的Nacos出了1.0.1版本,从去年7月份第一个release版本到现在一直在默默关注 官方的版本规划为:Nacos从0.8.0开始支持生产可用,1.0版本可大规模生产可用,2. ...
- coo ceo cfo cto cio 区别
常见的CEO(Chief executive officer)首席执行官类似总经理.总裁,是企业的法人代表. COO(Chief operating officer)首席运营官 类似常务总经理CFO( ...
- Spring学习之旅(十二)--持久化框架
对于本职工作来说 JDBC 就可以很好的完成,但是当我们对持久化的需求变得更复杂时,如: 延迟加载 预先抓取 级联 JDBC 就不能满足了,我们需要使用 ORM框架 来实现这些需求. Spring 对 ...
- HDU 6363
题意略. 思路: 这里有两个结论需要注意: 1.gcd(a ^ x - 1,a ^ y - 1) = a ^ gcd(x,y) - 1 2.gcd(fib[x],fib[y]) = fib[gcd(x ...
- Codeforces 814D
题意略. 思路: 由于不重合这个性质,我们可以将每一个堆叠的圆圈单独拿出来考虑,而不用去考虑其他并列在同一层的存在, 在贪心解法下,发现,被嵌套了偶数层的圆圈永远是要被减去的,而奇数层的圆圈是要加上的 ...
- Codeforces 976E
题意略. 思路: 容易知道那a次倍增放在同一个怪身上是最优的,其余的怪我们只需要取hp值和damage值中间最大的那个就好了(在b值的限制下). 然而我们并不知道把那a次倍增放在哪个怪身上最好,那么我 ...