Commit 3edd93c9 authored by liyuanhong's avatar liyuanhong

并发线程脚本开发完成

parent 634a7493
# 模拟程序说明文档 # 模拟程序说明文档
#### (一)、框架结构说明 #### (一)、框架结构说明
\ No newline at end of file config:存放项目配置文件
dada:存放项目需要的数据和产生的数据
doc:项目帮助文档,markdown格式编写
img:存放项目需要的图片资源
lib:车机协议实现的类,以及各种业务逻辑
log:项目运行日志文件
static:存放网页端图形操作界面的静态文件,包含:js,css,图片等
templates:存放网页模板文件 html
views:存放网页端操作的后台处理逻辑,以及页面的展示逻辑
run.py:启动项目图形操作界面主程序,访问:127.0.0.1:5000 即可
requirements.txt:设置项目需要的依赖库
### (二)、文档目录
[1、lib使用库说明](doc/lib_details.md)
[2、如何使用web图形操作界面](https://www.baidu.com/)
### (三)、图形界面展示
#### m500操作界面:
![alt text](doc/img/m500_1.png "Title Text")
#### 车安优操作界面:
![alt text](doc/img/new_hard_1.png "Title Text")
\ No newline at end of file
# lib库使用说明
### (一)、lib库目录结构
#coding:utf-8 #coding:utf-8
import binascii import binascii
import json import json
import random
import socket import socket
import threading import threading
import time import time
from random import random
from lib.multiThread.ThreadBase import ThreadBase from lib.multiThread.ThreadBase import ThreadBase
from lib.protocol.message.Location_msg import Location_msg from lib.protocol.message.Location_msg import Location_msg
...@@ -16,12 +16,18 @@ class SendMultMsgThread(): ...@@ -16,12 +16,18 @@ class SendMultMsgThread():
self.host = host self.host = host
self.port = port self.port = port
self.msg = msg self.msg = msg
self.timeOut = 1 #socket超时时间 self.timeOut = 60 #socket超时时间
self.BUF_SIZE = 1024 #接收消息缓存 self.BUF_SIZE = 1024 #接收消息缓存
self.threadCount = 10 #并发线程数 self.threadCount = 5000 #并发线程数
self.totalTime = 0 #所有线程的运行总和 self.totalTime = 0 #所有线程的运行总和
self.threadArr = {} #保存每个线程的信息 self.threadArr = {} #保存每个线程的信息
self.failThreadCount = 0 #失败线程数 self.failThreadCount = 0 #失败线程数
self.durThreads = [] #持续发送线程数组,当数组为空,表示所有线程已经结束
self.durTime = 60 #线程持续时间
self.connectTimeoutNum = 0 #连接超时线程数
self.sendTimeoutNum = 0 #发送超时线程数
self.reviceTimeoutNum = 0 #接收超时线程数
self.sucessNum = 0 #成功线程数
pass pass
############################################ ############################################
...@@ -82,9 +88,66 @@ class SendMultMsgThread(): ...@@ -82,9 +88,66 @@ class SendMultMsgThread():
############################################ ############################################
# 持续发送消息 # 持续发送消息
# dur: 持续发送时间,如果为0一直发送, 设置了事件为持续发送多少秒,默认为一分钟
############################################ ############################################
def sendMsgContinuous(self): def sendMsgContinuous(self,carId,threadName="thread0"):
pass client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳
client.settimeout(self.timeOut)
startTime = int(time.time())
endTime = int(time.time())
self.durThreads.append(threadName)
try:
client.connect((self.host, self.port))
except BaseException as e:
client.close()
self.durThreads.remove(threadName)
self.threadArr[threadName]["status"] = 1
self.failThreadCount = self.failThreadCount + 1
endTime = int(time.time())
timeExpend = endTime - startTime
self.threadArr[threadName]["timeExp"] = timeExpend
self.connectTimeoutNum = self.connectTimeoutNum + 1
print(threadName + ":" + "连接超时,socket断开")
return
while (endTime - startTime) < self.durTime:
msg = self.getRandomMsg(carId)
try:
client.send(binascii.a2b_hex(msg))
except BaseException as e:
client.close()
self.durThreads.remove(threadName)
self.threadArr[threadName]["status"] = 1
self.failThreadCount = self.failThreadCount + 1
endTime = int(time.time())
timeExpend = endTime - startTime
self.threadArr[threadName]["timeExp"] = timeExpend
self.sendTimeoutNum = self.sendTimeoutNum + 1
print(threadName + ":" + "发送超时,socket断开")
return
try:
data = client.recv(self.BUF_SIZE)
except BaseException as e:
client.close()
self.durThreads.remove(threadName)
self.threadArr[threadName]["status"] = 1
self.failThreadCount = self.failThreadCount + 1
self.reviceTimeoutNum = self.connectTimeoutNum + 1
print(threadName + ":" + 'socket 接收消息超时!')
endTime = int(time.time())
timeExpend = endTime - startTime
self.threadArr[threadName]["timeExp"] = timeExpend
return
endTime = int(time.time())
sleepTime = random.randint(1, 5)
time.sleep(sleepTime)
endTime = int(time.time())
timeExpend = endTime - startTime
self.threadArr[threadName]["timeExp"] = timeExpend
client.close()
self.sucessNum = self.sucessNum + 1
self.durThreads.remove(threadName)
############################################ ############################################
# 启动并发线程 # 启动并发线程
...@@ -92,8 +155,7 @@ class SendMultMsgThread(): ...@@ -92,8 +155,7 @@ class SendMultMsgThread():
def startThread(self): def startThread(self):
timeStart = int(time.time() * 1000) timeStart = int(time.time() * 1000)
for i in range(0,self.threadCount): for i in range(0,self.threadCount):
threadName = "thread" + str(i) threadName = "thread-" + str(i)
carid = 201912000000 + i
theThread = threading.Thread(target=self.sendMsg, args=("7e0002000001314620111800065b7e",threadName,)) # 数据写死,心跳 theThread = threading.Thread(target=self.sendMsg, args=("7e0002000001314620111800065b7e",threadName,)) # 数据写死,心跳
threadInfo = {} threadInfo = {}
threadInfo["name"] = threadName threadInfo["name"] = threadName
...@@ -102,7 +164,7 @@ class SendMultMsgThread(): ...@@ -102,7 +164,7 @@ class SendMultMsgThread():
theThread.start() theThread.start()
timeEnd = int(time.time() * 1000) timeEnd = int(time.time() * 1000)
timeExpend = timeEnd - timeStart timeExpend = timeEnd - timeStart
time.sleep(20) time.sleep(3)
print("耗时:" + str(timeExpend) + " 毫秒") print("耗时:" + str(timeExpend) + " 毫秒")
print("并发数据每秒发送:" + str(int(self.threadCount / (timeExpend / 1000)))) print("并发数据每秒发送:" + str(int(self.threadCount / (timeExpend / 1000))))
print("平均响应时间:" + str(self.totalTime / self.threadCount) + "毫秒") print("平均响应时间:" + str(self.totalTime / self.threadCount) + "毫秒")
...@@ -110,6 +172,38 @@ class SendMultMsgThread(): ...@@ -110,6 +172,38 @@ class SendMultMsgThread():
print("响应失败数:" + str(self.failThreadCount)) print("响应失败数:" + str(self.failThreadCount))
self.writeToFile("../../data/threadDetails.json",self.threadArr) self.writeToFile("../../data/threadDetails.json",self.threadArr)
############################################
# 启动持续并发线程
############################################
def startThreadContinuous(self):
timeStart = int(time.time() * 1000)
for i in range(0,self.threadCount):
threadName = "thread-" + str(i)
print(threadName)
carid = 201912000000 + i
theThread = threading.Thread(target=self.sendMsgContinuous, args=(carid,threadName,)) # 数据写死,心跳
threadInfo = {}
threadInfo["name"] = threadName
threadInfo["status"] = 0
self.threadArr[threadName] = threadInfo
theThread.start()
timeEnd = int(time.time() * 1000)
timeExpend = timeEnd - timeStart
print("耗时:" + str(timeExpend) + " 毫秒产生了" + str(self.threadCount) + "线程")
while len(self.durThreads) != 0:
print("剩余线程数:" + str(len(self.durThreads)))
time.sleep(5)
print("-------------------------- 统计信息 --------------------------")
print("耗时:" + str(timeExpend) + " 毫秒产生了" + str(self.threadCount) + "线程")
print("设置socket超时时间:" + str(self.timeOut))
print("设置线程持续时间:" + str(self.durTime))
print("成功线程数:" + str(self.sucessNum))
print("连接失败:" + str(self.connectTimeoutNum))
print("发送失败:" + str(self.sendTimeoutNum))
print("接收失败:" + str(self.reviceTimeoutNum))
self.writeToFile("../../data/threadDetailsContinuous.json",self.threadArr)
def writeToFile(self,path,data): def writeToFile(self,path,data):
with open(path, "w", encoding='utf-8') as fi: with open(path, "w", encoding='utf-8') as fi:
json.dump(data, fi) json.dump(data, fi)
...@@ -117,39 +211,65 @@ class SendMultMsgThread(): ...@@ -117,39 +211,65 @@ class SendMultMsgThread():
#获取随机消息数据 #获取随机消息数据
def getRandomMsg(self,carId): def getRandomMsg(self,carId):
#carid = 201912010002 # carId = 201912010002
wh = random.randint(0,3) wh = random.randint(0,2)
msg = "" msg = ""
if wh == 0: if wh == 0:
hearbeat_msg = "4040000b000c4d" + carId + "0003b59f" hearbeat_msg = "4040000e00044d" + str(carId) + "8000000300cf91"
hearbeat_msg = hearbeat_msg[:-4] + self.crc16(hearbeat_msg[:-4])
msg = hearbeat_msg msg = hearbeat_msg
elif wh == 1: elif wh == 1:
GPS_msg = "4040003d000e4d" + carId + "0010011403040a0e0501c329ed0659dec501f402e8000000b4050a0b0c9305050258001400000fa0000000005e5f68e75e5f7f6d9ec9" GPS_msg = "4040003d00054d" + str(carId) + "001001140305031e0301c329ed0659dec501f402e8000000b4050a0b0c9305050258001400000fa0000000005e606f115e60723be44b"
GPS_msg = GPS_msg[:-4] + self.crc16(GPS_msg[:-4])
msg = GPS_msg msg = GPS_msg
elif wh == 2: elif wh == 2:
OBD_msg = "4040007000034d" + carId + "0012011403040a101b26d7fffff0000000000505000000143c00000bb80100000fa00000000a000000000000000003e803e839331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e00000000000000000000006487" OBD_msg = "4040007000064d" + str(carId) + "00120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e00000000000000000000007213"
OBD_msg = OBD_msg[:-4] + self.crc16(OBD_msg[:-4])
msg = OBD_msg msg = OBD_msg
return msg return msg
if __name__ == "__main__": ####################################################
t = SendMultMsgThread() # 定义生成校验字段的函数
# t.setMsg("7e0002000001314620111800065b7e") # inputStr:需要传入一个已经转换为16进制的字符串
# t.setMsg("7e020001020131462011190001fffc7fff001c010401c0a6380659ad7a02090042003b200204185704310102EA6600010400000000000204001e7c1f0003050A0001f400000405020001d4c000050400057d0240000604000119400007040007530000100c0004006403f203f203f203f2001114ffffffffffffffffffff00200000000000000000001202002400130106001D0101EB7960C0020bb860D0013c62f00203216050014c60F0015860B001146330011c646001416490012060A00201146014010160100102610002022661100201f561F0020e746210040000119c6040012c60700200e660E00203206701010067020100670301016704024e20670502000067060200416707040000017d02097e") #####################################################
t.startThread() # add crc 16 check at the end of the string
def crc16(self,inputStr):
inputStrByte = bytes.fromhex(inputStr)
crc = 0xFFFF
for i in range(0, len(inputStrByte)):
for j in range(0, 8):
c15 = (crc >> 15) == 1
bit = ((inputStrByte[i] >> (7 - j)) & 1) == 1
crc <<= 1
crc &= 0xFFFF
if c15 ^ bit:
crc ^= 0x1021
crc = str(hex(crc))
crc = self.leftPad(crc[2:], 4)
# outputStr = inputStr + crc
outputStr = crc
return outputStr
# pad zero to the left of the string if not long enough
def leftPad(self,inputStr, strLen):
if (strLen > len(inputStr)):
outputStr = "0000000000000000000000000000000000000000" + inputStr
outputStr = outputStr[len(outputStr) - strLen:]
return outputStr
else:
return inputStr
# pad zero to the right of the string if not long enough
def rightPad(self,inputStr, strLen):
if (strLen > len(inputStr)):
outputStr = inputStr + "0000000000000000000000000000000000000000"
outputStr = outputStr[: strLen]
return outputStr
else:
return inputStr
if __name__ == "__main__":
t = SendMultMsgThread()
t.setHost("10.100.12.32")
t.setPort(9008)
# t.startThread()
t.startThreadContinuous()
\ No newline at end of file
...@@ -88,7 +88,7 @@ class ProtocolBase(Base): ...@@ -88,7 +88,7 @@ class ProtocolBase(Base):
##################################################### #####################################################
# 将字符串转换为对应的ascii值数组 # 将字符串转换为对应的ascii值数组
##################################################### #####################################################
def str2Ascsii(s): def str2Ascsii(self,s):
asciiArr = [] asciiArr = []
for i in range(0, len(s)): for i in range(0, len(s)):
asciiValue = ord(s[i]) asciiValue = ord(s[i])
...@@ -194,6 +194,8 @@ if __name__ == "__main__": ...@@ -194,6 +194,8 @@ if __name__ == "__main__":
# print(ProtocolBase().str2Hex("a")) # print(ProtocolBase().str2Hex("a"))
# print(ProtocolBase().int2hexStringByBytes(1,6)) # print(ProtocolBase().int2hexStringByBytes(1,6))
# print(ProtocolBase().num2signedNum(-5)) # print(ProtocolBase().num2signedNum(-5))
print(ProtocolBase().getUTCTimeHex("2020-01-03 13:05:13")) # print(ProtocolBase().getUTCTimeHex("2020-01-03 13:05:13"))
print(ProtocolBase().hex2UTCTime("1401030d050d")) # print(ProtocolBase().hex2UTCTime("1401030d050d"))
print(ProtocolBase().hex2UTCTime("14020a07122b")) # print(ProtocolBase().hex2UTCTime("14020a07122b"))
print(ProtocolBase().crc16("4040007000064d20191201000200120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e0000000000000000000000"))
print(ProtocolBase().myCrc16("4040007000064d20191201000200120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e0000000000000000000000"))
...@@ -100,9 +100,9 @@ def str2Ascsii(s): ...@@ -100,9 +100,9 @@ def str2Ascsii(s):
if __name__ == "__main__": if __name__ == "__main__":
print(crc16(str2Hex("aa"))) # print(crc16(str2Hex("aa")))
print(str2Hex("aa")) # print(str2Hex("aa"))
print(str2HexStrip("aa")) # print(str2HexStrip("aa"))
print(str2Ascsii("aa")) # print(str2Ascsii("aa"))
print(myCrc16("aa")) print(myCrc16("4040007000064d20191201000200120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e0000000000000000000000"))
print(crc16(str2HexStrip("aa"))) # print(crc16(str2HexStrip("aa")))
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
<div style="background:#222222;height:50px;"></div> <div style="background:#222222;height:50px;"></div>
<div style="width: 70%;margin: 0 auto"> <div style="width: 70%;margin: 0 auto">
<ul class="nav nav-tabs" style="font-size:18px;"> <ul class="nav nav-tabs" style="font-size:18px;">
<li role="presentation" {% if arg.path[0]=="protocolTools" %} class="active" {% endif %}><a onclick="swichTap(this)" id="protocolTools">协议工具</a></li> <li role="presentation" {% if arg.path[0]=="protocolTools" %} class="active" {% endif %}><a onclick="swichTap(this)" id="protocolTools">M500协议工具</a></li>
<li role="presentation" {% if arg.path[0]=="messageTools" %} class="active" {% endif %}><a onclick="swichTap(this)" id="messageTools">消息工具</a></li> <li role="presentation" {% if arg.path[0]=="messageTools" %} class="active" {% endif %}><a onclick="swichTap(this)" id="messageTools">新硬件消息工具</a></li>
<li role="presentation" {% if arg.path[0]=="tab1" %} class="active" {% endif %}><a onclick="swichTap(this)" id="tab1">案例</a></li> <li role="presentation" {% if arg.path[0]=="tab1" %} class="active" {% endif %}><a onclick="swichTap(this)" id="tab1">案例</a></li>
<li role="presentation" {% if arg.path[0]=="tab2" %} class="active" {% endif %}><a onclick="swichTap(this)" id="tab2">演示页面</a></li> <li role="presentation" {% if arg.path[0]=="tab2" %} class="active" {% endif %}><a onclick="swichTap(this)" id="tab2">演示页面</a></li>
<li role="presentation" {% if arg.path[0]=="other" %} class="active" {% endif %}><a onclick="swichTap(this)" id="otherTab">其他</a></li> <li role="presentation" {% if arg.path[0]=="other" %} class="active" {% endif %}><a onclick="swichTap(this)" id="otherTab">其他</a></li>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment