from socket import *
import tkinter as tk
import tkinter.scrolledtext as tst
import time
import tkinter.messagebox
import threading
import binascii
import sys
import os
import re
from datetime import datetime
# 68d900060000000e81000001ff000001c8000000
APDU_DATA_LEN = 20
# 68d900
APDU_START_LEN = 3
# 060000000e81000001ff000001c8000000
APDU_CONCROL_DATA_LEN = 17
file_CFG_data_len_Had = 0
file_DAT_data_len_Had = 0
lawPfvBuf = b""
fileName = "103demo"
cfgfilename = fileName + '.cfg'
datfilename = fileName + '.dat'
# 定义输入服务器ip地址的类
class inputIPdialog(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.ipInput = tk.Text(self, width=30, height=5)
self.ipInput.insert(tk.END, "172.17.68.34")
self.ipInput.grid(row=0, column=0, columnspan=3)
self.okbtn = tk.Button(self, text='确定', command=self.setIP).grid(row=1, column=3)
self.grid()
def setIP(self):
# 这个global变量作为类变量的话没有效果,原因不知
global servername
servername = self.ipInput.get('1.0', 'end-1c')
# 销毁窗口
ipRootFrame.destroy()
class Application(tk.Frame):
def __init__(self, master):
self.init__ = tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def createWidgets(self):
# self.inputText = tk.Text(self, width=10, height=1)
# self.inputText = tk.Text(self)
# # self.inputText.grid(row=3, columnspan=8)
# self.inputText.grid(row=3, rowspan=20, columnspan=8)
# # 定义快捷键,按下回车即可发送消息
# self.inputText.bind("<KeyPress-Return>", self.textSendReturn)
self.btnSend5 = tk.Button(self, text='清空显示', command=self.clearTextEdit)
self.btnSend5.grid(row=2, column=0)
self.btnSend1 = tk.Button(self, text='建立连接', command=self.textSend1)
self.btnSend1.grid(row=1, column=0)
self.btnSend2 = tk.Button(self, text='1#录波报文列表', command=self.textSend2)
self.btnSend2.grid(row=1, column=1)
self.btnSend3 = tk.Button(self, text='1#录波报文', command=self.textSend3)
self.btnSend3.grid(row=1, column=2)
self.btnSend4 = tk.Button(self, text='1#定值00区', command=self.textSend4)
self.btnSend4.grid(row=1, column=3)
self.btnSend5 = tk.Button(self, text='1#定值01区', command=self.textSend5)
self.btnSend5.grid(row=1, column=4)
self.btnSend6 = tk.Button(self, text='1#定值02区', command=self.textSend6)
self.btnSend6.grid(row=1, column=5)
self.btnSend7 = tk.Button(self, text='1#当前定值区号', command=self.textSend7)
self.btnSend7.grid(row=1, column=6)
self.btnSend8 = tk.Button(self, text='4#当前定值区号', command=self.textSend8)
self.btnSend8.grid(row=2, column=6)
self.btnSend9 = tk.Button(self, text='4#定值00区', command=self.textSend9)
self.btnSend9.grid(row=2, column=3)
self.btnSend10 = tk.Button(self, text='4#定值01区', command=self.textSend10)
self.btnSend10.grid(row=2, column=4)
self.btnSend11 = tk.Button(self, text='4#定值02区', command=self.textSend11)
self.btnSend11.grid(row=2, column=5)
self.btnSend12 = tk.Button(self, text='4#录波报文列表', command=self.textSend12)
self.btnSend12.grid(row=2, column=1)
self.btnSend13 = tk.Button(self, text='4#录波报文', command=self.textSend13)
self.btnSend13.grid(row=2, column=2)
self.labelPfvInfo = tk.Label(self, text="").grid(row=3, column=0)
# 定值相关参数
self.labeladdr = tk.Label(self, text="装置地址:").grid(row=4, column=0)
self.labelZone = tk.Label(self, text="定值区号:").grid(row=4, column=2)
PfvAddr = tk.StringVar()
PfvAddr.set('1')
PfvZone = tk.StringVar()
PfvZone.set('1')
self.entryAddr = tk.Entry(self, textvariable=PfvAddr)
self.entryAddr.grid(row=4, column=1, sticky=tk.W)
self.entryZone = tk.Entry(self, textvariable=PfvZone)
self.entryZone.grid(row=4, column=3, sticky=tk.W)
self.btnPfv = tk.Button(self, text='读取定值', command=self.textSendPfv)
self.btnPfv.grid(row=4, column=4)
self.btnZone = tk.Button(self, text='读取当前定值区号', command=self.textSendZone)
self.btnZone.grid(row=4, column=5)
# 定值相关参数
self.labelWaveaddr = tk.Label(self, text="起始时间:").grid(row=5, column=0)
self.labelWaveYear = tk.Label(self, text="年:").grid(row=6, column=0)
self.labelWaveMonth = tk.Label(self, text="月:").grid(row=7, column=0)
self.labelWaveDay = tk.Label(self, text="日:").grid(row=8, column=0)
WaveStartYear = tk.StringVar()
WaveStartYear.set('14')
WaveStartMonth = tk.StringVar()
WaveStartMonth.set('1')
WaveStartDay = tk.StringVar()
WaveStartDay.set('1')
self.entryStartYear = tk.Entry(self, textvariable=WaveStartYear)
self.entryStartYear.grid(row=6, column=1, sticky=tk.W)
self.entryStartMonth = tk.Entry(self, textvariable=WaveStartMonth)
self.entryStartMonth.grid(row=7, column=1, sticky=tk.W)
self.entryStartDay = tk.Entry(self, textvariable=WaveStartDay)
self.entryStartDay.grid(row=8, column=1, sticky=tk.W)
self.labelWaveaddrEnd = tk.Label(self, text="结束时间:").grid(row=5, column=2)
self.labelWaveYearEnd = tk.Label(self, text="年:").grid(row=6, column=2)
self.labelWaveMonthEnd = tk.Label(self, text="月:").grid(row=7, column=2)
self.labelWaveDayEnd = tk.Label(self, text="日:").grid(row=8, column=2)
WaveEndYear = tk.StringVar()
WaveEndYear.set('15')
WaveEndMonth = tk.StringVar()
WaveEndMonth.set('3')
WaveEndDay = tk.StringVar()
WaveEndDay.set('1')
self.entryEndYear = tk.Entry(self, textvariable=WaveEndYear)
self.entryEndYear.grid(row=6, column=3, sticky=tk.W)
self.entryEndMonth = tk.Entry(self, textvariable=WaveEndMonth)
self.entryEndMonth.grid(row=7, column=3, sticky=tk.W)
self.entryEndDay = tk.Entry(self, textvariable=WaveEndDay)
self.entryEndDay.grid(row=8, column=3, sticky=tk.W)
self.btnWave = tk.Button(self, text='读取录波列表', command=self.textSendWavelist)
self.btnWave.grid(row=6, column=4)
# 显示读取列表名称
self.labelWaveaddr1 = tk.Label(self, text="显示读取列表名称:").grid(row=9, column=0, sticky=tk.W)
self.textEditWaveList = tst.ScrolledText(self, width=110, height=20)
self.textEditWaveList.grid(row=10, rowspan=10, columnspan=8)
self.textEditWaveList.bind("<KeyPress-Return>", self.textSendReturn)
# 发送要读取的录波文件
self.labelWaveaddr2 = tk.Label(self, text="读取录波文件:").grid(row=22, column=0, sticky=tk.W)
self.textEditSendWave = tst.ScrolledText(self, width=110, height=10)
self.textEditSendWave.grid(row=30, rowspan=10, columnspan=8)
self.textEditSendWave.bind("<KeyPress-Return>", self.textSendReturn)
# 读录波文件按钮
self.btnSendWave = tk.Button(self, text='读文件', command=self.textSendWavefile)
self.btnSendWave.grid(rowspan=6, columnspan=7, sticky=tk.E)
# 发送自己编写的报文
self.labelWaveaddr3 = tk.Label(self, text="发送自己编写的报文:").grid(row=22, column=15, sticky=tk.W)
# self.textEdit1 = tk.Text(self, width=10, height=1)
self.textEdit1 = tst.ScrolledText(self, width=110, height=10)
# self.textEdit1 = tst.ScrolledText(self)
self.textEdit1.grid(row=23, column=15, rowspan=20, columnspan=8)
self.textEdit1.bind("<KeyPress-Return>", self.textSendReturn)
# 发送发送自己编写的报文按钮
self.btnSend = tk.Button(self, text='send', command=self.textSend)
self.btnSend.grid(row=43, column=15, rowspan=6, columnspan=7, sticky=tk.E)
# 显示收发报文窗口
self.textEdit = tst.ScrolledText(self, width=105, height=50)
self.textEdit.grid(row=1, column=15, rowspan=20, columnspan=8)
# self.textEdit.grid(row=1, column=10 ,sticky=tk.E)
# self.textEdit.config(state='disabled')
# 定义标签,改变字体颜色
self.textEdit.tag_config('server', foreground='red')
self.textEdit.tag_config('guest', foreground='blue')
# 开启一个线程用于接收消息并显示在窗口
t = threading.Thread(target=self.getInfo)
t.start()
# 开启一个线程用于发送建立连接帧,保持通讯,并显示在窗口
t1 = threading.Thread(target=self.sendConnect)
t1.start()
def textSendWavefile(self):
'''
读取装置地址和定值区号填替换到固定列表
68 38 00 06 00 38 00 0D 81 00 00 01 FF 00 37
32 30 31 32 30 31 31 31 31 35
31 32 34 36 34 31 38 5f 31 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00
68 38 00 06 00 38 00 0D 81 00 00 04 FF 00 37
32 30 31 32 30 31 31 31 31 35
31 32 34 36 34 31 38 5f 34 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00
:return:
'''
# 检查该程序路径下是否有cfg及dat文件,全部删除
global cfgfilename
global datfilename
base_dir = os.path.dirname(__file__)
filenameCfg = base_dir + "/" + cfgfilename
filenameDat = base_dir + "/" + datfilename
if os.path.exists(filenameCfg):
os.remove(filenameCfg)
if os.path.exists(filenameDat):
os.remove(filenameDat)
# 发送读取录波文件命令
str1111 = self.entryAddr.get()
strgetWaveName = self.textEditSendWave.get('1.0', 'end-1c')
str = '68 38 00 06 00 38 00 0D 81 00 00 {addr} FF 00 37 {filename} 00 00 00 00 '.format(
addr=str1111.zfill(2),
filename=strgetWaveName)
# print(str)
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSendWavelist(self):
'''
读取装置地址和定值区号填替换到固定列表
68 1A 00 06 00 36 00 0F 81 00 00 01 FF 00 37 00 00 00 00 A1 0C 0b 00 00 00 00 92 01 0C
68 1A 00 06 00 36 00 0F 81 00 00 04 FF 00 37 00 00 00 00 A1 0C 0b 00 00 00 00 92 01 0C
:return:
'''
self.textEditWaveList.get(0.0, tk.END)
self.textEditWaveList.delete(0.0, tk.END) # 删除输入框的内容
str1111 = self.entryAddr.get()
strWaveStartYear = self.entryStartYear.get()
strWaveStartMonth = self.entryStartMonth.get()
strWaveStartDay = self.entryStartDay.get()
strWaveEndYear = self.entryEndYear.get()
strWaveEndMonth = self.entryEndMonth.get()
strWaveEndDay = self.entryEndDay.get()
str = '68 1A 00 06 00 36 00 0F 81 00 00 {addr} FF 00 37 00 00 00 00 ' \
'{WaveStartDay} {WaveStartMonth} {WaveStartYear} 00 00 00 00 ' \
'{WaveEndDay} {WaveEndMonth} {WaveEndYear}'.format(
addr=str1111.zfill(2),
WaveStartYear=strWaveStartYear.zfill(2),
WaveStartMonth=strWaveStartMonth.zfill(2),
WaveStartDay=strWaveStartDay.zfill(2),
WaveEndYear=strWaveEndYear.zfill(2),
WaveEndMonth=strWaveEndMonth.zfill(2),
WaveEndDay=strWaveEndDay.zfill(2))
# print(str)
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSendZone(self):
'''
读取装置地址和定值区号填替换到固定列表
68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 00 00 0A
# 装置地址为4的当前定值区号
68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 00 00 0A
:return:
'''
str1111 = self.entryAddr.get()
str = '68 10 00 06 00 36 00 15 81 2A 00 {addr} FF F1 37 01 00 00 0A'.format(addr=str1111.zfill(2))
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSendPfv(self):
'''
读取装置地址和定值区号填替换到固定列表
68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 01 01 0A
68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 01 02 0A
68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 01 00 0A
68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 01 02 0A
:return:
'''
str1111 = self.entryAddr.get()
str1112 = self.entryZone.get()
# s1 = '%05d' % str1111
# s2 = '%05d' % str1112
str = '68 10 00 06 00 36 00 15 81 2A 00 {addr} FF F1 37 01 01 {zone} 0A'.format(addr=str1111.zfill(2),
zone=str1112.zfill(2))
# print(str)
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend(self):
# 获取Text的所有内容
# https://stackoverflow.com/questions/14824163/how-to-get-the-input-from-the-tkinter-text-box-widget
# str = self.inputText.get('1.0', 'end-1c')
str = self.textEdit1.get('1.0', 'end-1c')
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def clearTextEdit(self):
self.textEdit.get(0.0, tk.END)
self.textEdit.delete(0.0, tk.END) # 删除输入框的内容
def textConfirmSformat(self):
str = '68 04 00 83 00 00 00'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textConfirmSend(self):
str = '68 04 00 83 00 00 00'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend1(self):
global clientSocket
global servername
global serverport
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect(('172.17.68.34', 2404))
# str = '68 04 00 07 00 00 00'
# if str != "" and str != None:
# # 显示发送时间和发送消息
# timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# # 通过设置state属性设置textEdit可编辑
# self.textEdit.config(state='normal')
#
# self.textEdit.insert(tk.END, timemsg, 'guest')
# self.textEdit.insert(tk.END, str + '\n')
#
# # 将滚动条拉到最后显示最新消息
# self.textEdit.see(tk.END)
# # 通过设置state属性设置textEdit不可编辑
# # self.textEdit.config(state='disabled')
# # self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# # 发送数据到服务端
# sendMessage = bytes.fromhex(str)
# # 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
# clientSocket.send(sendMessage)
# else:
# tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend2(self):
# 1#装置录波报文列表,
# 开始时间:11年12月1日
# 结束CP56Time2a时间:12年1月18日
str = '68 1A 00 06 00 36 00 0F 81 00 00 01 FF 00 37 00 00 00 00 A1 0C 0b 00 00 00 00 92 01 0C'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
# 读取录波报文
def textSend3(self):
# 读取装置地址为1录波文件cfg,dat
str = '68 38 00 06 00 38 00 0D 81 00 00 01 FF 00 37 32 30 31 32 30 31 31 31 31 35 31 ' \
'32 34 36 34 31 38 5f 31 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' \
'00 00 00 00'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend12(self):
# 4#装置录波报文列表,
# 开始时间:11年12月1日
# 结束CP56Time2a时间:12年1月18日
str = '68 1A 00 06 00 36 00 0F 81 00 00 04 FF 00 37 00 00 00 00 A1 0C 0b 00 00 00 00 92 01 0C'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
# 读取录波报文
def textSend13(self):
# 读取装置地址为4录波文件cfg,dat
str = '68 38 00 06 00 38 00 0D 81 00 00 04 FF 00 37 32 30 31 32 30 31 31 31 31 35 31 ' \
'32 34 36 34 31 38 5f 34 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' \
'00 00 00 00'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend4(self):
# 1# 定值00区
str = "68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 01 00 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend5(self):
# 1# 定值01区
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 01 01 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend6(self):
# 1# 定值02区
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 01 02 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend7(self):
# 装置地址为1的当前定值区号
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 01 FF F1 37 01 00 00 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend8(self):
# 装置地址为4的当前定值区号
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 00 00 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend9(self):
# 4# 定值00区
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 01 00 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend10(self):
# 4# 定值01区
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 01 01 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def textSend11(self):
# 4# 定值02区
# str = "68 1A 00 06 00 36 00 15 81 2A 00 01 FF 00 37 00 01 01 00 A1 0C 0b 00 00 00 00 92 01 0C"
str = "68 10 00 06 00 36 00 15 81 2A 00 04 FF F1 37 01 01 02 0A"
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 通过设置state属性设置textEdit不可编辑
self.textEdit.config(state='disabled')
# self.inputText.delete(0.0, tk.END) # 删除输入框的内容
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def sendConnect(self):
# 发送测试链路应答帧
str = '68 04 00 07 00 00 00'
if str != "" and str != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, str + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 发送数据到服务端
sendMessage = bytes.fromhex(str)
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
def getInfo(self):
global clientSocket
global file_CFG_data_len_Had
global file_DAT_data_len_Had
global lawPfvBuf
n = 0
global cfgfilename
global datfilename
starttime = time.time()
while True:
# 接收数据,1024指定缓存长度,使用的是recv方法
# recMessage = clientSocket.recv(1024).decode("utf8") + '\n'
recMessage1 = clientSocket.recv(3)
if len(recMessage1) > 2:
rrrdate = recMessage1[1:3]
recMessagelen = len(recMessage1)
recvDataLen = int(recMessage1[1]) + int(recMessage1[2]) * 256
recMessage2 = clientSocket.recv(recvDataLen)
if recvDataLen > 10:
ASDU = recMessage2[4]
ASDUAddr = recMessage2[8]
# fileName = "104fileAddr" + str(ASDUAddr)
if ASDU == 14: # fileName = "103demo"
# cfgfilename = fileName + '.cfg'
# datfilename = fileName + '.dat'
recMessage = recMessage1 + recMessage2
recMessageStr = recMessage.hex()
if re.search(r'68[0-9a-zA-Z]{12}0e81[0-9a-zA-Z]{6}ff00[]0-9a-zA-Z]{2}[]0-9a-zA-Z]{2}',
recMessageStr):
if re.search(
r'68[0-9a-zA-Z]{12}0e81[0-9a-zA-Z]{6}ff00[]0-9a-zA-Z]{2}[]0-9a-zA-Z]{2}00000000',
recMessageStr):
# print("CFG第一帧")
FILETYPE = recMessage2[69]
FILFTYPELEN = int(recMessage2[70]) + int(recMessage2[71]) * 256 \
+ int(recMessage2[72]) * 256 * 256 \
+ int(recMessage2[73]) * 256 * 256 * 256
if FILETYPE == 2:
file_CFG_data = recMessage2[74:]
file_CFG_data_len = len(file_CFG_data)
if file_CFG_data_len_Had < FILFTYPELEN:
file_CFG_data_len_Had += file_CFG_data_len
with open(cfgfilename, 'ab+') as file_obj:
file_obj.write(file_CFG_data)
elif FILETYPE == 3:
pass
else:
if FILETYPE == 2:
file_CFG_data = recMessage2[APDU_CONCROL_DATA_LEN:]
file_CFG_data_len = len(file_CFG_data)
file_CFG_data_len_Had_Old = file_CFG_data_len_Had
file_CFG_data_len_Had += file_CFG_data_len
if file_CFG_data_len_Had <= FILFTYPELEN:
with open(cfgfilename, 'ab+') as file_obj:
file_obj.write(file_CFG_data)
else:
tempReadCFGLen = FILFTYPELEN - file_CFG_data_len_Had_Old
file_CFG_data = recMessage2[
APDU_CONCROL_DATA_LEN:tempReadCFGLen + APDU_CONCROL_DATA_LEN]
with open(cfgfilename, 'ab+') as file_obj:
file_obj.write(file_CFG_data)
# print(file_CFG_data)
file_CFG_data_len_Had = 0
FILETYPE = recMessage2[APDU_CONCROL_DATA_LEN + tempReadCFGLen]
FILFTYPELEN = int(recMessage2[APDU_CONCROL_DATA_LEN + tempReadCFGLen + 1]) \
+ int(
recMessage2[APDU_CONCROL_DATA_LEN + tempReadCFGLen + 2]) * 256 \
+ int(
recMessage2[APDU_CONCROL_DATA_LEN + tempReadCFGLen + 3]) * 256 * 256 \
+ int(
recMessage2[APDU_CONCROL_DATA_LEN + tempReadCFGLen + 4]) * 256 * 256 * 256
if FILETYPE == 3:
tempReadDATLen = recvDataLen - tempReadCFGLen - APDU_CONCROL_DATA_LEN
file_DAT_data = recMessage2[tempReadCFGLen + APDU_CONCROL_DATA_LEN + 5:]
file_DAT_data_len_Had = len(file_DAT_data)
with open(datfilename, 'ab+') as file_dat:
file_dat.write(file_DAT_data)
# print(file_DAT_data)
else:
if FILETYPE == 3:
file_DAT_data = recMessage2[APDU_CONCROL_DATA_LEN:]
file_DAT_data_len = len(file_DAT_data)
file_DAT_data_len_Had_Old = file_DAT_data_len_Had
file_DAT_data_len_Had += file_DAT_data_len
if file_DAT_data_len_Had <= FILFTYPELEN:
with open(datfilename, 'ab+') as file_obj:
file_obj.write(file_DAT_data)
else:
tempReadDATLen = FILFTYPELEN - file_DAT_data_len_Had_Old
file_DAT_data = recMessage2[APDU_CONCROL_DATA_LEN:
tempReadDATLen + APDU_CONCROL_DATA_LEN]
with open(datfilename, 'ab+') as file_obj:
file_obj.write(file_DAT_data)
# print(file_DAT_data)
file_DAT_data_len_Had = 0
elif ASDU == 10:
followBuf = recMessage2[12]
if followBuf == 1:
lawPfvBuf += recMessage2[13:]
# print(lawPfvBuf)
# print(len(lawPfvBuf))
else:
lawPfvBuf += recMessage2[13:]
AllPfvBufData = lawPfvBuf
AllPfvBufDataLen = len(AllPfvBufData)
# print(AllPfvBufData)
# print(AllPfvBufDataLen)
lawPfvBuf = b''
# for pfvFloat in range(AllPfvBufDataLen/10):
# print(pfvFloat)
# print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5")
# recPfvMessageStr = recMessage.hex()
# if re.search(r'68[0-9a-zA-Z]{12}0a81[0-9a-zA-Z]{6}ff00[]0-9a-zA-Z]{2}[]0-9a-zA-Z]{2}',
# recPfvMessageStr):
elif ASDU == 16:
recMessage = recMessage1 + recMessage2
recMessageStr = recMessage.hex()
m = re.search(r'68[0-9a-zA-Z]{12}1081[0-9a-zA-Z]{6}ff0000[0-9a-zA-Z]{2}([]0-9a-zA-Z]{2})',
recMessageStr)
if m == None:
pass
else:
waveNums = int(m.group(1))
for waveNum in range(waveNums):
StartNum = 66
oneWavefileName = 104
readStartNum = StartNum + waveNum * oneWavefileName
if waveNum < waveNums - 1:
readEndNum = StartNum + (waveNum + 1) * oneWavefileName
waveNameSize = recMessageStr[readStartNum: readEndNum]
else:
waveNameSize = recMessageStr[readStartNum:]
waveName = waveNameSize[:80]
# print(waveName)
# print(type(waveNum))
n = n + 1
# print("ASDU16-jinru" + str(n))
self.textEditWaveList.config(state='normal')
# server作为标签,改变字体颜色
self.textEditWaveList.insert(tk.END, waveName)
self.textEditWaveList.insert(tk.END, '\n')
# 将滚动条拉到最后显示最新消息
self.textEditWaveList.see(tk.END)
# self.textEditWaveList.config(state='disabled')
else:
pass
recMessage = recMessage1 + recMessage2
# print(recMessage)
recData = binascii.b2a_hex(recMessage)
# 接受时间和接收的数据
recTime = '接收' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
self.textEdit.config(state='normal')
# server作为标签,改变字体颜色
self.textEdit.insert(tk.END, recTime, 'server')
self.textEdit.insert(tk.END, recData)
self.textEdit.insert(tk.END, '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
self.textEdit.config(state='disabled')
startSstr = "68040100"
strS_send = startSstr + recMessage[3:5].hex()
if strS_send != "" and strS_send != None:
# 显示发送时间和发送消息
timemsg = '发送' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
# 通过设置state属性设置textEdit可编辑
self.textEdit.config(state='normal')
self.textEdit.insert(tk.END, timemsg, 'guest')
self.textEdit.insert(tk.END, strS_send + '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
# 发送数据到服务端
sendMessage = bytes.fromhex(strS_send)
# 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
clientSocket.send(sendMessage)
else:
tk.messagebox.showinfo('警告', "不能发送空白信息!")
else:
recMessage = recMessage1 + recMessage2
recData = binascii.b2a_hex(recMessage)
# 接受时间和接收的数据
recTime = '接收' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
self.textEdit.config(state='normal')
# server作为标签,改变字体颜色
self.textEdit.insert(tk.END, recTime, 'server')
self.textEdit.insert(tk.END, recData)
self.textEdit.insert(tk.END, '\n')
# 将滚动条拉到最后显示最新消息
self.textEdit.see(tk.END)
self.textEdit.config(state='disabled')
if recvDataLen == 4:
self.textConfirmSend()
else:
start = time.time()
def textSendReturn(self, event):
if event.keysym == "Return":
self.textSend()
# 指定服务器地址,端口
servername = '172.17.68.34'
serverport = 2404
ipRootFrame = tk.Tk()
ipRootFrame.title('输入服务器ip')
ipDialog = inputIPdialog(ipRootFrame)
ipDialog.mainloop()
# socket第一个参数指定使用IPV4协议,第二个参数指定这是一个TCP套接字
clientSocket = None
try:
clientSocket = socket(AF_INET, SOCK_STREAM)
except:
tk.messagebox.showinfo('未知错误', '检查服务器地址是否错误!')
# tcp连接需要先经过握手建立连接
# try:
# clientSocket.connect((servername, serverport))
# except:
# tk.messagebox.showinfo('提示', '检查服务器未打开!')
def callbackClose():
clientSocket.close()
root.destroy()
try:
connectReturn = clientSocket.connect((servername, serverport))
root = tk.Tk()
root.title('网络103客户端' + sys.argv[0])
root.geometry('1580x900')
root.resizable(0, 0)
# click the top right close button response to events
root.protocol("WM_DELETE_WINDOW", callbackClose)
# make Esc exit the program
root.bind('<Escape>', lambda e: root.destroy())
app = Application(master=root)
app.mainloop()
except ConnectionRefusedError:
tk.messagebox.showinfo('提示', '检查服务器是否打开!')
finally:
ipDialog.destroy()
网友评论