树莓派:基于物联网做的指纹打卡器

  今天我就分享一波自己的成果。

  心心念念的想做一个物联网的东西出来,终于在上个月搞定了,虽说肯定是有些漏洞(目前我是没有找出来的),但是效果看起来还不错。学了这么久的Python、Qt、liunx命令总算派上用场了。

材料:

  • 树莓派一台
  • 指纹模块(AS608光学指纹识别模块)
  • OLED液晶屏
  • usb转TTL
  • 杜邦线

 

先说明一下

博客园无法分享附件就只能这样分享了

如果想要附件可以点击下面 链接,我在csdn上注册了一个号可以去下载:

树莓派上的源码下载

电脑上的上位机源码下载

oled上的字体

 

先上个最终成果的图

 

           

 

看起来感觉还可以,基本完成了电脑和手机都可以获得日志的效果

 

大家最期待的过程了

  现在我来说是我的想法和思路

  刚开始看到隔壁实验室的指纹打卡机时好像是那种用usb读取数据的(好像是节约成本吧),我就想能这也太不智能了吧,就想着能不能让它智能些,比如通过电脑看到它的日志啊,或者用手机看到它的日志啊什么的(后来我才知道淘宝上TM已经出现这种完善的成品指纹考勤机了)。光想没用啊,还是要靠实践来检验真理。于是我就想到了手上的树莓派,想想就有些兴奋,可以向网上那些大佬一样DIY一个东西出来了,由于我的知识有限,无法自己搞个指纹打卡模块,就到网上买了一个,先开始买的正点原子的指纹模块,原子哥不愧是我原子哥,和他讨论问题时真是尽心尽力。文档很好,不过他那个和模块通信的程序不是很全,就几个,可以能是直接储存在模块里的缘故,可是我不想储存在模块里啊,我学了Python加上Mysql,我想直接存在数据库里,这样更加安全可靠。于是我就开始解决通信问题,将他发回来的数据解码,捣鼓了2天才完成,有点心酸。

先把配置文件分享了,下面代码会用到

# 用户root 给电脑连接的
[root]
pwd = 123

# 数据库
[db]
db_port = 3306
db_user = root
db_host = 127.0.0.1
db_pwd = 123456
db_database = finger
db_table = test1

# smtpServer 发送请求服务
# popServer 接收请求服务
# smtpSrcAddr 服务端的地址
# smtpSrcAddrPwd 服务端的密码
# smtpDstAddr 发送的目的邮箱
# smtpPort 端口号  qq端口号为 465
[email]
smtpServer = smtp.qq.com
popServer = pop.qq.com
smtpSrcAddr = 发送请求的你的邮箱
smtpSrcAddrPwd = 允许的密码
smtpDstAddr = 目的邮箱
smtpPort = 465 # TCP服务 [TCP] ip = 192.168.137.249 port = 9090 # 串口服务 [serial] port = /dev/ttyAMA0 (先不用这个串口,这个是我配置过的,你可以先用usb转ttl连接树莓派的usb口和指纹模块) baudrate = 57600 timeout = 10 # 乐联网 网关信息 [lewei] ip = tcp.lewei50.com port = 9960 userKey = 你自己的userKey gatewayNode = 02

 

1.首先要在电脑上调通指纹发送数据的所有命令

 分享一波代码

要用电脑和指纹模块通信首先要装

python要serial模块,在cmd命令行中用命令 pip install serial 就可以下载serial 了

  1 # -*-coding=utf8-*-
  2 
  3 import serial
  4 import serial.tools.list_ports
  5 
  6 import os, sys
  7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  8 sys.path.append(PATH)
  9 
 10 SureCore = {
 11     0x00: True,  # 表示指令执行完毕或OK;
 12     0x01: 101,  # 表示数据包接收错误;
 13     0x02: 102,  # 表示传感器上没有手指;
 14     0x03: 103,  # 表示录入指纹图像失败;
 15     0x06: 202,  # 表示指纹图像太乱而生不成特征;
 16     0x07: 203,  # 表示指纹图像正常,但特征点太少而生不成特征;
 17     0x15: 204,  # 表示图像缓冲区内没有有效原始图而生不成图像;
 18     0x08: 302,  # 表示指纹不匹配;
 19     0x09: 402,  # 表示没搜索到;此时页码与得分为 0
 20     0x0a: 502,  # 表示合并失败(两枚指纹不属于同一手指);
 21     0x0d: 802,  # 表示指令执行失败;
 22     0x0f: 1002,  # 表示不能发送后续数据包;
 23 }
 24 '''返回= 999 校验和错误'''
 25 
 26 
 27 class DealBuff:
 28     """切割收到的数据"""
 29     HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
 30 
 31     def __init__(self, buff):
 32         self.buff = buff
 33         """处理读出的指纹数据用到"""
 34         self.tag = list()  # 包标识
 35         self.data = list()
 36         self.check = list()
 37         pass
 38 
 39     def read(self):
 40         buff = [x for x in bytes(self.buff)]
 41         check = self.slit(buff)
 42         return self.tag, self.data, check
 43 
 44     def listCut(self, buff, num):
 45         """切割数组"""
 46         rec = list()
 47         for i in range(num):
 48             bytes_buf = (buff.pop(0))
 49             # rec.append(buff.pop(0))
 50             rec.append(bytes_buf)
 51         return rec, buff
 52         pass
 53 
 54     def slit(self, buff):
 55         """"选择数据"""
 56         # 初始化中间变量
 57         popList = list()
 58         check_Num = 0
 59         check = list()
 60         head = list()
 61 
 62         if len(buff) < 6:  # 判断是否有效数据
 63             return True
 64 
 65         head, buff = self.listCut(buff, 6)  # 选择出头及判断
 66         for i in range(6):
 67             if head[i] != self.HEAD[i]:
 68                 return False
 69 
 70         popList, buff = self.listCut(buff, 1)  # 取出包标识
 71         self.tag.append(popList)
 72         check_Num += popList[0]  # 计算校验和
 73 
 74         popList, buff = self.listCut(buff, 2)  # 取出包长度
 75         check_Num += popList[0] + popList[1]  # 计算校验和
 76 
 77         popList, buff = self.listCut(buff, popList[0] * 16 + popList[1])  # 取出包数据
 78         check.append(popList.pop())  # 取出校验数据
 79         check.append(popList.pop())
 80         for i in popList:  # 计算校验和
 81             check_Num += i
 82 
 83         self.data.extend(popList)  # 导入有用数据
 84         if check_Num % 65535 != check[0] + check[1]*256:  # 检验校验和
 85             return False
 86 
 87         rec = self.slit(buff)  # 得到是否正确分析完数据
 88         return rec
 89         pass
 90 
 91     def write(self):
 92         """要写的数据打包"""
 93         pack = self.dataSeparate(self.buff, 128)   # 将数据分成每组128个元素
 94         return pack
 95         pass
 96 
 97     def dataSeparate(self, buff, numPart):
 98         """把数据分组打包"""
 99         num = int(len(buff) / numPart)
100         newData = list()
101         for i in range(num):
102             newData.append(buff[i * numPart:(i+1) * numPart])
103 
104         packData = list()
105         for i in range(num-1):
106             data = self.packData(newData[i], 0x02)  # 数据包没结束
107             packData.extend(data)
108 
109         packData.extend(self.packData(newData[num-1], 0x08))  # 数据包结束
110         return packData
111         pass
112 
113     def packData(self, buff, flage):
114         num = len(buff) + 2
115         senddata = [flage, int(num / 256), int(num % 256)] + buff
116         sum = 0
117         for i in senddata:
118             sum += i
119         senddata = self.HEAD + senddata
120         senddata.append(int(sum / 256))
121         senddata.append(int(sum % 256))
122         return senddata
123         pass
124 
125     pass
126 
127 
128 class DealFingeer:
129     """和指纹模块交互"""
130     HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
131     tag = list()  # 包标识
132     cmd = list()  #
133     data = list()
134     ser = serial.Serial()
135     def __init__(self, cmd, data=None, server=None):
136         """初始化函数"""
137         self.cmd = cmd
138         self.data = data
139         self.server = server
140         pass
141 
142     def run(self):
143         if hasattr(self, self.cmd):
144             func = getattr(self, self.cmd)
145             return func(self.data)
146         pass
147 
148     def link(self):
149         """连接串口"""
150         self.ser.port = "COM5"
151         self.ser.baudrate = 57600
152         self.ser.bytesize = 8
153         self.ser.parity = 'N'
154         self.ser.xonxoff = 0
155         self.ser.rtscts = 0
156         self.ser.close()
157         self.ser.open()
158         pass
159 
160     def finger(self, data):
161         self.link()
162         check = self.getImage()  # 检测获取图像
163         if check is not True:
164             return check, []
165 
166         self.link()
167         check = self.genChar(data)  # 检测生成特征值
168         if check is not True:
169             return check, []
170         # ================= 生成特征值时图像会清除,所以要重新采集 ========================== #
171         self.link()
172         check = self.getImage()  # 检测获取图像
173         if check is not True:
174             return check, []
175 
176         if self.server is not None:
177             self.server.send("True".encode("utf8"))  # 发送数据说明准备好了
178 
179         self.link()
180         check = self.upImage()  # 上传图像
181         if check is not True:    # 校验和错误
182             return check, []
183         self.tag, self.data = self.getUpImage()
184 
185         if len(self.tag) is 0 and len(self.data) is 0:  # 得到数据错误
186             return False, []
187         return True, []
188 
189     def save(self, data=None):
190         self.link()
191         check = self.regModel()
192         if check is not True:    # 校验和错误
193             return check, []
194 
195         self.link()
196         check = self.upChar(data)  # 上传特征值
197         if check is not True:  # 校验和错误
198             return check, []
199         self.tag, self.data = self.getUpChar()
200 
201         if len(self.tag) is 0 and len(self.data) is 0:  # 得到数据错误
202             return False, []
203         return True, []
204         pass
205 
206     def check(self, data=None):
207         """检验指纹, 生成特征值"""
208         self.link()
209         check = self.match()   # 比较指纹特征
210         if check is not True:
211             return check, []
212         score = self.data[1]*255 + self.data[2]  # 返回的分数值
213 
214         self.link()
215         check = self.regModel()  # 合成指纹特征值
216         if check is not True:
217             return check, []
218         return True, score
219         pass
220 
221     def isFinger(self, data=None):
222         """判断现在的指纹和下载的指纹是否相同"""
223         self.link()
224         check = self.downCharCheck()
225         if check is not True:    # 判断是否可以发送数据
226             return check, []
227         """下载指纹"""
228         self.link()
229         self.downCharData(data)
230         """检验指纹"""
231         self.link()
232         check = self.match()
233         if check is not True:
234             return check, []
235         score = self.data[1] * 255 + self.data[2]  # 返回的分数值
236         return True, score
237         pass
238 
239     def getImage(self, data=None):
240         """获取图像"""
241         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05]   # 发送命令获取内容
242         return self.isOk(cmd, 12)
243         pass
244 
245     def genChar(self, data=None):
246         """生成特征文件"""
247         if data == "1":
248             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x01, 0x00, 0x08]  # 发送命令
249             return self.isOk(cmd, 12)  # 图像接收数据 12 大小
250         elif data == "2":
251             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x02, 0x00, 0x09]  # 发送命令
252             return self.isOk(cmd, 12)  # 图像接收数据 12 大小
253         pass
254 
255     def match(self, data=None):
256         """比较指纹特征"""
257         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x03, 0x00, 0x07]   # 发送命令获取内容
258         return self.isOk(cmd, 14)
259         pass
260 
261     def regModel(self, data=None):
262         """合成指纹特征值"""
263         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09]   # 发送命令获取内容
264         return self.isOk(cmd, 12)
265         pass
266 
267     def upChar(self, data=None):
268         """上传特征模块检测"""
269         buff = bytes()
270         if data == "1":
271             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x01, 0x00, 0x0e]  # 发送命令
272             return self.isOk(cmd, 12, False)
273         elif data == "2":
274             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0F]  # 发送命令
275             return self.isOk(cmd, 12, False)
276         pass
277 
278     def getUpChar(self, data=None):
279         """上传特征模块数据"""
280         buff = self.ser.read(834)
281         self.ser.close()
282         subpackage = DealBuff(buff)   # 分割内容
283         self.tag, self.data, check = subpackage.read()
284         if check is not True:    # 校验和错误
285             return 999
286         return self.tag, self.data
287 
288     def downCharCheck(self, data=None):
289         """
290         下载特征值检测
291         先要初始化,发送获取图像命令
292         """
293         self.getImage()
294         self.link()
295         cmd = self.HEAD + [0x01, 0x00, 0x04, 0x09, 0x02, 0x00, 0x10]  # 发送命令 下载的数据放在buff2中
296         return self.isOk(cmd, 12)
297         pass
298 
299     def downCharData(self, data):
300         """下载特征值的数据"""
301         self.writeRead(data, 0)  # 发送数据 接收为0
302         pass
303 
304 
305     def upImage(self, data=None):
306         """上传图像检测"""
307         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x0a, 0x00, 0x0e]  # 发送命令
308         return self.isOk(cmd, 12, False)
309         pass
310 
311     def getUpImage(self, data=None):
312         """获取后续的图像数据"""
313         buff = self.ser.read(40032)
314         self.ser.close()
315         subpackage = DealBuff(buff)   # 分割内容
316         self.tag, self.data, check = subpackage.read()
317         if check is not True:    # 校验和错误
318             return [], []
319         return self.tag, self.data
320 
321     def writeRead(self, cmd, length, close=True):
322         """发送命令读取原始字节"""
323         cmd = bytes(cmd)
324         self.ser.write(cmd)
325         buff = self.ser.read(length)   # 图像接收数据
326         if close:
327             self.ser.close()    # 接受完数据断开com
328         return buff
329         pass
330 
331     def isOk(self, cmd, length, close=True):
332         """判断数据是否合格"""
333         buff = self.writeRead(cmd, length, close)  # 图像接收数据 12 大小
334         subpackage = DealBuff(buff)   # 分割内容
335         self.tag, self.data, check = subpackage.read()
336         # 检验数据是否可靠
337         if check is not True:   # 校验和错误
338             return 999
339         return self.check_code(self.data)
340         pass
341 
342     def check_code(self, data):
343         """检验指令码"""
344         return SureCore[data[0]]
345         pass
346 
347     pass
348 
349 
350 if __name__ == "__main__":
351     # HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
352     # data = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x0A, 0x00, 0x0E]
353     # data = HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05]
354     # data = HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09]
355     # data = HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0f]
dealFinger.py

 注意:

  1. 可以先在串口调试助手上输入命令,看看数据是怎么样子的然后在分析数据,最后写程序处理数据
  2. 按照说明书提示最好不要改 模块的地址和密码,不然可能会成为砖头
  3. 非常重要!!!本人是吃了亏的,真是日了狗, 指纹模块中有个设置波特率的,说明书上是说波特率可以设置为9600倍数,其实并不是这样的,我先开始觉得速度太慢了就设置了先开始是12倍,觉得可以用还是太慢,就设置了24倍,还是可以用,但是还是慢,我一冲动就设置成了96倍,我的个乖乖,然后就是不管怎么唤它都没反应,为此我还和原子哥讨论了很久,结果就是这东西成板砖了。 然后不得已就又买了个便宜的(原子哥虽然服务好,技术支持好,就是东西太贵了,弄懂原理了就不用再买贵的了)。

2.就是写一个服务器和客户端啦

我是用Qt写的客户端,用python写的服务器,模拟两个电脑通信(虽然只要一个自己的电脑)

 先来一波服务器的代码

里面用到了mySql, 用来存储指纹数据

 同时为了上传图像到客户端还要下载numpy, PIL 模块,其中python3中没有PIL 要下pillow

用到的cmd命令 pip install numpy,  pip install pillow

  1 # -*-coding=utf8-*-
  2 
  3 import socketserver
  4 from collections import Iterable
  5 import json
  6 
  7 import os, sys
  8 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  9 sys.path.append(PATH)
 10 
 11 from core import dealFinger
 12 from core.dealFinger import DealFinger
 13 from core.dealSql import mySqlDeal
 14 from core import dealFile
 15 from core import clockIn
 16 import core
 17 
 18 import configparser
 19 
 20 check = {
 21     0x00: True,  # 表示指令执行完毕或OK;
 22     0x01: 101,  # 表示数据包接收错误;
 23     0x02: 102,  # 表示传感器上没有手指;
 24     0x03: 103,  # 表示录入指纹图像失败;
 25     0x06: 202,  # 表示指纹图像太乱而生不成特征;
 26     0x07: 203,  # 表示指纹图像正常,但特征点太少而生不成特征;
 27     0x15: 204,  # 表示图像缓冲区内没有有效原始图而生不成图像;
 28     0x08: 302,  # 表示指纹不匹配;
 29     0x09: 402,  # 表示没搜索到;此时页码与得分为 0
 30     0x0a: 502,  # 表示合并失败(两枚指纹不属于同一手指);
 31     0x0d: 802,  # 表示指令执行失败;
 32     0x0f: 1002,  # 表示不能发送后续数据包;
 33     "occupyError": "occupyError",  # 占用指纹资源失败
 34     "releaseError": "releaseError",  # 释放指纹资源失败
 35     "getLogError": "getLogError",  # 获取日志失败
 36     "findError": "findError",  # 查找人失败
 37     "outPutError": "outPutError"  # 导出数据库失败
 38 }
 39 
 40 isTcpOccupy = 0
 41 
 42 class JudgeLoad:
 43     """判断是否是合理的用户登陆"""
 44     def __init__(self, server, addrIP):
 45         self.server = server
 46         self.addrIP = addrIP
 47         pass
 48 
 49     def isLoad(self, data, addr):
 50         """判断是否登陆成功"""
 51         if isinstance(data, dict):
 52             isTrue1 = self.isFind("userName", data.keys())   # 判断类型是否符合
 53             isTrue2 = self.isFind("passWord", data.keys())   # 判断类型是否符合
 54             if isTrue1 is True and isTrue2 is True:
 55                 return self.isUser(data["userName"], data["passWord"], addr)
 56             else:
 57                 isTrue = self.isFind(self.addrIP, addr)  # 判断是否有登陆过
 58                 if isTrue is not True:
 59                      return False
 60                 isTrue1 = self.isFind("cmd", data.keys())  # 判断类型是否符合
 61                 isTrue2 = self.isFind("value", data.keys())  # 判断类型是否符合
 62                 if isTrue1 is True and isTrue2 is True:
 63                     return True
 64             return False
 65         return False
 66         pass
 67 
 68     def isUser(self, user, pwd, addr):
 69         """判断用户名和密码是否正确"""
 70         try:
 71             cf = configparser.ConfigParser
 72             cf = dealFile.readConf(cf)
 73             pwdconf = cf.get(user, "pwd")
 74             if pwd == pwdconf:
 75                 ischeck = self.isFind(self.addrIP, addr)
 76                 if ischeck is not True:
 77                     addr.append(self.addrIP)  # 添加主机ip 确定登陆成功
 78                 self.server.send("True".encode("utf8"))
 79                 return "loadSuccess"
 80         except Exception as e:
 81             print(e)
 82         return "loadFalse"
 83         pass
 84 
 85     def isFind(self, child, parent):
 86         """寻找parent 中是否有 child"""
 87         if isinstance(parent, Iterable) is not True:   # 判断是否是可迭代类型
 88             return False
 89         for i in parent:
 90             if child == i:
 91                 return True
 92         return False
 93         pass
 94 
 95     pass
 96 
 97 
 98 class SeverHandle(socketserver.BaseRequestHandler):
 99     """
100     任务分发
101     将客户端的请求分发下去
102     """
103     # addr = ["127.0.0.1"]
104     addr = list()
105     Occupy = list()
106     def init(self):
107         self.Finger = None
108         pass
109 
110     def handle(self):
111         """连接的一个客户端"""
112         self.init()
113         print("------------------连接成功-----------------")
114         print("conn :", self.request)
115         print("addr :", self.client_address)
116         # 接收客户端数据
117         buff = self.request.recv(1024).decode("utf8")
118         data = eval(buff)
119 
120         judgeLode = JudgeLoad(self.request, self.client_address[0])
121         isTrue = judgeLode.isLoad(data, self.addr)  # 判断是否登陆
122         if isTrue is not True:
123             if isTrue is "loadSuccess":
124                 return
125             elif isTrue is "loadFalse":
126                 print("error")
127                 self.request.send("error".encode("utf8"))
128                 return
129             elif isinstance(data, dict):
130                     isTrue1 = judgeLode.isFind("cmd", data.keys())  # 判断类型是否符合
131                     isTrue2 = judgeLode.isFind("value", data.keys())  # 判断类型是否符合
132                     if isTrue1 is True and isTrue2 is True:
133                         print("error")
134                         self.request.send("error".encode("utf8"))
135             return
136 
137         print(data)
138         if hasattr(self, data["cmd"]):     # 命令分发
139             func = getattr(self, data["cmd"])
140             func(data["cmd"], data["value"])
141         pass
142 
143     def finger(self, cmd, value):
144         """采集手指数据"""
145         self.Finger = DealFinger(cmd, value, self.request)
146         check, buff = self.Finger.run()
147         if check is not True:
148             self.request.send(str(check).encode("utf8"))
149             return
150         print(self.Finger.data)
151         fileName = dealFile.createImage(self.Finger.data, "finger.bmp")
152         self.sendData(fileName)
153 
154     def check(self, cmd, value):
155         """检验指纹是否合格"""
156         self.Finger = DealFinger(cmd, value, self.request)
157         check, score = self.Finger.run()
158 
159         if check is not True:
160             self.request.send(str(check).encode("utf8"))
161             return
162         senddata = "%s##%s" % ("True", score)   # 拼接发送格式
163         self.request.send(senddata.encode("utf8"))
164         pass
165 
166     def save(self, cmd, data):
167         """储存数据到数据库"""
168         self.Finger = DealFinger(cmd, "2")   # 读取buff2 中的模板
169         check, buff = self.Finger.run()
170 
171         if check is not True:
172             self.request.send(str(check).encode("utf8"))
173             return
174         """储存到硬件"""
175         dataFinger = list()
176         dataFinger.append(self.Finger.data)
177         self.Finger = DealFinger("saveToHard")   # 读取buff2 中的模板
178         check, buff = self.Finger.run()
179         if check is not True:
180             self.request.send(str(check).encode("utf8"))
181             return
182         print(buff)
183         num = buff[1] * 256 + buff[2]
184         print(num)
185         """储存到数据库里"""
186         print(data)
187         buff = data.split("##")
188         data = {
189             "num": num,
190             "id": buff[0],
191             "name": buff[1],
192             "date": buff[2],
193             "finger": str(dataFinger[0])
194         }
195         sql = mySqlDeal("insertData", data)   # 储存指纹
196         sql.run()
197         print("save True......")
198         self.request.send("True".encode("utf8"))  # 发送成功信息
199         """发送更新检测指纹"""
200         core.qIsNewSql.put(True)
201         pass
202 
203     def occupy(self, cmd, data):
204         global isTcpOccupy
205         """抢占指纹"""
206         if isTcpOccupy is 1:
207             senddata = "%s" % (check["occupyError"])  # 拼接发送格式
208             self.request.send(senddata.encode("utf8"))
209             return
210 
211         core.qToClockOccupy.put(True)
212 
213         if isTcpOccupy is 2:
214             pop = self.Occupy.pop()
215             print(pop)
216             if pop != self.client_address[0]:
217                 senddata = "%s" % (check["occupyError"])  # 拼接发送格式
218                 self.request.send(senddata.encode("utf8"))
219                 return
220         self.Occupy.append(self.client_address[0])  # 记录哪个客户端
221 
222         isTcpOccupy = 2   # 标记客户端抢占的
223         self.request.send("True".encode("utf8"))  # 发送成功信息
224 
225     def release(self, cmd, data):
226         """释放指纹"""
227         global isTcpOccupy
228 
229         core.qToClockOccupy.put(False)
230 
231         if isTcpOccupy is 0:
232             senddata = "%s" % (check["releaseError"])  # 拼接发送格式
233             self.request.send(senddata.encode("utf8"))
234             return
235         isTcpOccupy = 0
236         self.Occupy.pop()
237         self.request.send("True".encode("utf8"))  # 发送成功信息
238 
239     def getLog(self, cmd, data):
240         """获取日志"""
241         fileName = dealFile.getFilePath("log.txt")
242         if fileName is False:
243             self.request.send(check["getLogError"].encode("utf8"))  # 发送成功信息
244             return
245         self.request.send("True".encode("utf8"))  # 发送成功信息
246         self.sendData(fileName)
247         pass
248 
249     def findPeople(self, cmd, data):
250         """查找人"""
251         sql = mySqlDeal("selectId", data)   # 查找
252         ch, data = sql.run()
253         if ch is False:
254             self.request.send(check["findError"].encode("utf8"))  # 发送成功信息
255             return
256         self.request.send("True".encode("utf8"))  # 发送成功信息
257         fileName = dealFile.createFindFile(data, "find.txt")
258         self.sendData(fileName)
259         pass
260 
261     def delectPeople(self, cmd, data):
262         """删除数据"""
263         sql = mySqlDeal("selectNum", data)   # 删除
264         check, fingerNum = sql.run()
265         for i in fingerNum:
266             num = int(i[0])
267             self.Finger = DealFinger("psDeletChar", num)
268             self.Finger.run()
269         sql = mySqlDeal("delectId", data)   # 删除
270         sql.run()
271         self.request.send("True".encode("utf8"))  # 发送成功信息
272         pass
273 
274     def databaseBack(self, cmd, data):
275         ch, fileName = dealFile.outPutSql("fingerSql.sql")
276         if ch is False:
277             self.request.send(check["outPutError"].encode("utf8"))  # 发送成功信息
278             return
279         self.request.send("True".encode("utf8"))  # 发送成功信息
280         self.sendData(fileName)
281         pass
282 
283     def updateDatabase(self, cmd, data):
284         buff = data.split("##")
285         fileName = buff[0]
286         fileSize = int(buff[1])
287         self.request.send("True".encode("utf8"))  # 发送成功信息
288         self.getFile(fileName, fileSize)
289         check = dealFile.creatSql(fileName)
290         if check is not True:
291             return None
292         mysql = mySqlDeal("selectAll")
293         check, data = mysql.run()
294         if check is not True:
295             return None
296         """储存指纹"""
297         self.Finger = DealFinger("creatFinger", data)
298         self.Finger.run()
299 
300         pass
301 
302     def close(self, cmd, data):
303         """客户端退出"""
304         for i in self.addr:
305             if i is self.client_address[0]:
306                 self.addr.remove(i)
307         pass
308 
309     def sendData(self, path):
310         """发送文件"""
311         fizeSize = os.path.getsize(path)
312         fileName = os.path.basename(path)
313         senddata = "{fileName}##{fileSize}" .format(fileName=fileName, fileSize=fizeSize)  # 拼接发送格式
314         self.request.send(senddata.encode("utf8"))
315         check = self.request.recv(1024).decode("utf8")
316         print("send......")
317         print(check)
318         if check != "True":     # 确定用户接收到了数据
319             self.request.send("error".encode("utf8"))
320             return
321         print("send......again")
322         with open(path, "rb") as f:   # 开始发送文件
323             num = 0
324             while num < fizeSize:
325                 data = f.read(1024)
326                 self.request.sendall(data)
327                 num += len(data)
328         print("send  ok")
329         pass
330 
331     def getFile(self, path, size):
332         fileName = dealFile.getFilePath(path)
333         fileSize = size
334         with open(fileName, "w") as f:  # 得到上传的文件
335             num = 0
336             while num < fileSize:
337                 data = self.request.recv(1024)
338                 num = num + len(data)
339                 data = data.decode("utf8")
340                 f.write(data)
341         print("get OK")
342     pass
343 
344 
345 def checkOccupy():
346     global isTcpOccupy
347     while True:
348         if isTcpOccupy == 0:
349             if core.qToTcpOccupy.empty() is not True:
350                 isTcpOccupy = core.qToTcpOccupy.get()
351     pass
352 
353 
354 if __name__ == "__main__":
355 
356     ip_port = ("192.168.137.249", 9090)
357     print("----等待连接.............")
358     s = socketserver.ThreadingTCPServer(ip_port, SeverHandle)
359 
360     s.serve_forever()
Tcpserver.py

 

 下面是服务器可能用到的

  1 # -*- coding:utf8 -*-
  2 
  3 import numpy as np
  4 from PIL import Image
  5 
  6 import os, sys
  7 import configparser
  8 
  9 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 10 sys.path.append(PATH)
 11 
 12 """存放文件的目录"""
 13 path = PATH + "/static/"
 14 
 15 """
 16 对文件的一下操作
 17 """
 18 
 19 
 20 def readConf(cf):
 21     """读取conf文件"""
 22     fileName = PATH + "/conf/" + "conf.conf"
 23     cf = configparser.ConfigParser()
 24     cf.read(fileName)
 25     return cf
 26 
 27 
 28 def createImage(data, fileName):
 29     """创建图像"""
 30     if isinstance(data, list) is not True:
 31         return False
 32     """得到指纹图像的灰度bmp图"""
 33     ByteArray = bytearray(data)  # 将数组转换成 字节数组
 34     NumpyArray = np.array(ByteArray)
 35     grayImage = NumpyArray.reshape(288, 128)  # 得到灰度图像字节数组
 36     image = Image.fromarray(grayImage)
 37     fileName = path + fileName   # 文件存放路径
 38     image.save(fileName)  # 得到指纹图像
 39     return fileName
 40     pass
 41 
 42 
 43 def textLog(data, fileName):
 44     """写日志"""
 45     fileName = path + fileName  # 文件存放路径
 46     with open(fileName, "a+") as f:
 47         f.write(data)
 48     return
 49     pass
 50 
 51 def getFilePath(fileName):
 52     """回取文件路径"""
 53     fileName = path + fileName
 54     if os.path.isfile(fileName) is False:
 55         return False
 56     return fileName
 57     pass
 58 
 59 def createFindFile(data, fileName):
 60     """生成查找文件"""
 61     fileName = path + fileName
 62     with open(fileName, "w+") as f:
 63         for i in data:
 64             id = "id  : " + i[0] + "\r\n"
 65             name = "name: " + i[1] + "\r\n"
 66             date = "date: " + i[2] + "\r\n"
 67             f.write(id + name + date + "\r\n")
 68     return fileName
 69 
 70 
 71 cf = configparser.ConfigParser()
 72 cf = readConf(cf)
 73 host = cf.get("db", "db_host")
 74 port = cf.getint("db", "db_port")
 75 user = cf.get("db", "db_user")
 76 passwd = cf.get("db", "db_pwd")
 77 db = cf.get("db", "db_database")
 78 table = cf.get("db", "db_table")
 79 
 80 """导出数据库"""
 81 def outPutSql(fileName, host=host, port=port, user=user, passwd=passwd, db=db, table=table):
 82     """导出mysql脚本"""
 83     fileName = path + fileName
 84     sqlStr = "mysqldump -u{user} -p{passwd} {db}> {fileName}"\
 85         .format(user=user, passwd=passwd, db=db, table=table, fileName=fileName)
 86     try:
 87         os.system(sqlStr)
 88     except Exception as e:  # 找不到数据库
 89         return False, None
 90     # print(os.path.getsize(fileName))
 91     return True, fileName
 92     pass
 93 
 94 
 95 """创建数据库"""
 96 def creatSql(fileName,  host=host, port=port, user=user, passwd=passwd, db=db, table=table):
 97     """创建数据库表"""
 98     fileName = path + fileName
 99     sqlStrDelect = "mysqladmin -u{user} -p{passwd} drop {db} -f"\
100         .format(user=user, passwd=passwd, db=db)
101     sqlStrCreat = "mysqladmin -u{user} -p{passwd} create {db}" \
102         .format(user=user, passwd=passwd, db=db, fileName=fileName)
103     sqlStrInsert = "mysql -u{user} -p{passwd} {db} < {fileName}" \
104         .format(user=user, passwd=passwd, db=db, fileName=fileName)
105     try:
106         """删除数据库"""
107         a = os.system(sqlStrDelect)
108         print(a)
109         """创建数据库"""
110         a = os.system(sqlStrCreat)
111         print(a)
112         """插入数据库"""
113         a = os.system(sqlStrInsert)
114         print(a)
115     except Exception as e:  # 找不到数据库
116         print(e)
117         return False, None
118     return True
119 
120 
121 def backFile(fileName, backName):
122     """备份文件"""
123     fileName = path + fileName
124     backName = path + backName
125     logcontent = path + "logContent.txt"
126     with open(fileName, "rb") as f1, open(backName, "wb") as f2:
127         data = f1.read()
128         f2.write(data)
129     with open(fileName, "w") as f1:
130         pass
131     """添加log目录"""
132     with open(logcontent, "a+") as f1:
133         f1.write(backName + "\r\n")
134     return True
135     pass
136 
137 
138 def joinFile():
139     """拼接日志"""
140     log = path + "log.txt"
141     logcontent = path + "logContent.txt"
142     logback = path + "logback.txt"
143     with open(logback, "w") as f2:
144         pass
145     with open(logcontent) as f1, open(logback, "a+") as f2:
146         data = f1.read().strip()
147         num = len(data)
148         if num == 0:   # 判断文科是否为空
149             with open(log) as f3:
150                 filestream = f3.read()
151                 f2.write(filestream)
152             return
153         data = data.split("\n")
154         print(data)
155         for i in data:
156             with open(i) as f3:
157                 filestream = f3.read()
158                 f2.write(filestream)
159         with open(log) as f3:
160             filestream = f3.read()
161             f2.write(filestream)
162     pass
163 
164 
165 def cleanFile():
166     """清空无用的日志文件"""
167     filename = path + "log_*"
168     logcontent = path + "logContent.txt"
169     with open(logcontent, "w"):  # 文件目录清空
170         pass
171     cmd = "rm {filename}".format(filename=filename)
172     data = os.system(cmd)
173     pass
174 
175 if __name__ == "__main__":
176     # print(PATH)
177     # print(type(PATH))
178     # print(path)
179     # print(type(path))
180     # print(createImage(123, 456))
181     # fileName = outPutSql("my.sql")
182     # print(fileName)
183     # print(os.path.getsize(fileName[1]))
184 
185     # backFile("simsun.ttc", "backsimsun.ttc")
186     joinFile()
187     # creatSql("123")
188     # cleanFile()
189     # logconvim tent = path + "logContent.txt"
190     # with open(logcontent) as f1:
191     #     data = f1.read().strip()
192     #     print(data)
193     #     num = len(data)
194     #
195     #     data = data.split("\n")
196     #     print(data)
dealFile.py

 

 

服务器完成后就可以写客户端端了。(其实是两个同时进行然后相互补充)

下面是Qt代码

主要是通讯,其他的界面其实都还好,就按照自己的想法

   1 #include "mainwindow.h"
   2 #include "ui_mainwindow.h"
   3 #include "QDebug"
   4 #include "QPainter"
   5 #include "QBrush"
   6 #include "QPaintDevice"
   7 #include "QMessageBox"
   8 #include "QSqlDatabase"
   9 #include "QSqlError"
  10 #include "QString"
  11 #include "QFileDialog"
  12 
  13 MainWindow::MainWindow(QWidget *parent) :
  14     QMainWindow(parent),
  15     ui(new Ui::MainWindow)
  16 {
  17     ui->setupUi(this);
  18     initData();//初始化数据函数
  19     initTcp();
  20 }
  21 
  22 MainWindow::~MainWindow()
  23 {
  24     delete ui;
  25 }
  26 
  27 
  28 //初始化数据函数
  29 void MainWindow::initData()
  30 {
  31     /* ================== 初始化登陆 ==================*/
  32     showImage = 3;
  33     //设置当前显示页面
  34     ui->stackedWidget->setCurrentWidget(ui->pageLog);
  35     //没登陆不使能菜单,设置密码不可见
  36     ui->menuO->setEnabled(false);
  37     //设置编辑框模式
  38     ui->lineEditUserName->setEnabled(true);
  39     ui->lineEditPassward->setEnabled(true);
  40     ui->lineEditPassward->setEchoMode(QLineEdit::Password);
  41     ui->pB_logoChangelink->setStyleSheet("#pB_logoChangelink{border: 0px;}"
  42                                          "#pB_logoChangelink:hover{color:rgb(0, 170, 255)};");
  43     isChangeLink=false;
  44     /* ================== 初始化界面1 ==================*/
  45     //显示文本框
  46     ui->textEdit_1_Show->setEnabled(true);
  47     ui->pushButton_1_get->setEnabled(true);
  48     ui->pushButton_1_show->setEnabled(true);
  49     ui->progressBar_1_get->setValue(0);
  50     ui->progressBar_1_get->hide();
  51     /* ================== 初始化界面2 ==================*/
  52     //button
  53     isOccupy = false;
  54     ui->pushButton_2_Start->setText("开启");
  55     ui->pushButton_2_Start->setEnabled(true);
  56     ui->pushButtonConcel->setEnabled(false);
  57     ui->pushButtonSure->setEnabled(false);
  58     ui->pushButtoncheckfinger->setEnabled(false);
  59     ui->pushButtonSavefinger1->setEnabled(false);
  60     ui->pushButtonSavefinger2->setEnabled(false);
  61     //label
  62     ui->label_2_info->setText("请放入手指!");
  63     ui->label_2_info->hide();
  64     //progressBar
  65     ui->progressBar_2_fingerImage->hide();
  66 
  67     /* ================ 初始化界面3 ====================== */
  68     findWhat = "id";
  69     ui->pushButton_3_findName->setText("查找id:");
  70     ui->pushButton_3_find->setEnabled(true);
  71     ui->lineEdit_3_findId->setEnabled(true);
  72     ui->pushButton_3_delect->setEnabled(false);
  73     ui->pushButton_3_back->setEnabled(true);  // 备份
  74     ui->pushButton_3_Updata->setEnabled(true); // 上传
  75     ui->progressBar_3_show->setValue(0);
  76     ui->progressBar_3_show->hide();
  77     ui->pushButton_3_findName->setStyleSheet("#pushButton_3_findName{border: 0px;}"
  78                                          "#pushButton_3_findName:hover{color:rgb(0, 170, 255)};");
  79 
  80 
  81     /*===================== tcp数据 ======================*/
  82     //文件接收
  83     isStart = true;
  84     //初始化tcp登陆
  85     isLoad = false;
  86     callFunc = 0;
  87     recWhat = 0;
  88     showInfo = false; 
  89 }
  90 
  91 //初始化有关tcp connect
  92 void MainWindow::initTcp()
  93 {
  94     //ip和端口
  95 //    ip = "127.0.0.1";
  96 //    port = 8080;
  97 
  98     ip = "192.168.137.249";
  99     port = 9090;
 100     //套接字
 101     tcpSocket = new QTcpSocket(this);
 102     //接收到服务器后发数据
 103     connect(tcpSocket, &QTcpSocket::connected, this, &MainWindow::sendDataToServe);
 104     //收信号
 105     connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::dealReceiveData);
 106     //对话框 × 掉
 107 //    connect(this, &MainWindow::destroyed, this, &MainWindow::on_actionClose_triggered);
 108      connect(this, &MainWindow::destroyed, this,
 109              [=]()
 110              {
 111                  qDebug() << "distory";
 112              }
 113      );
 114 }
 115 
 116 //设置tcp连接
 117 bool MainWindow::tcpLink(int mode)
 118 {
 119     //tcp连接等待超时
 120     tcpSocket->disconnectFromHost();
 121     tcpSocket->close();
 122     tcpSocket->connectToHost(QHostAddress(ip), port);
 123 
 124     if(!tcpSocket->waitForConnected(100))  //等待5s
 125     {
 126         if(0 == mode)
 127         {
 128             recCheck("link_error");
 129         }
 130         return false;
 131     }
 132     return true;
 133 }
 134 
 135 //成功连接服务器后的响应
 136 void MainWindow::sendDataToServe()
 137 {
 138     switch (callFunc) {
 139     case 1: {//登陆请求
 140         //给对方发送数据,使用套接字是tcpSocket;  QString->QByteArray->char*
 141         QString userName = ui->lineEditUserName->text();
 142         QString passWord = ui->lineEditPassward->text();
 143         QString sendData = QString("{'userName':'%1', 'passWord':'%2'}")
 144                 .arg(userName).arg(passWord);
 145         tcpSocket->write(sendData.toUtf8().data());
 146     }
 147         break;
 148     case 2: {//发送录制指纹1
 149         QString cmd = "finger";
 150         QString data = "1";
 151         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 152         tcpSocket->write(sendData.toUtf8().data());
 153     }
 154         break;
 155     case 3: {//发送录制指纹2
 156         QString cmd = "finger";
 157         QString data = "2";
 158         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 159         tcpSocket->write(sendData.toUtf8().data());
 160     }
 161         break;
 162     case 4: {//发送校验信息
 163         QString cmd = "check";
 164         QString data = "None";
 165         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 166         tcpSocket->write(sendData.toUtf8().data());
 167     }
 168         break;
 169     case 5: {//存储有效指纹数据
 170         QString cmd = "save";
 171         QString name = ui->lineEditname->text();
 172         QString id = ui->lineEditID->text();
 173         QString date = ui->lineEditdate->text();
 174         QString data = QString("%1##%2##%3").arg(id).arg(name).arg(date);
 175         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 176         tcpSocket->write(sendData.toUtf8().data());
 177     }
 178         break;
 179     case 6:{ // 发送占用指纹资源
 180         QString cmd = "occupy";
 181         QString data = "None";
 182         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 183         tcpSocket->write(sendData.toUtf8().data());
 184     }
 185         break;
 186     case 7:{ // 发送释放指纹资源
 187         QString cmd = "release";
 188         QString data = "None";
 189         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 190         tcpSocket->write(sendData.toUtf8().data());
 191     }
 192         break;
 193     case 8:{ // 界面1获取log
 194         QString cmd = "getLog";
 195         QString data = "None";
 196         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 197         tcpSocket->write(sendData.toUtf8().data());
 198     }
 199         break;
 200     case 9:{ // 查找人
 201         QString cmd = "findPeople";
 202         QString data = QString("%1:%2").arg(findWhat).arg(ui->lineEdit_3_findId->text());
 203         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 204         tcpSocket->write(sendData.toUtf8().data());
 205     }
 206         break;
 207     case 10:{ // 删除信息
 208         QString cmd = "delectPeople";
 209         QString data = QString("%1:%2").arg(findWhat).arg(ui->lineEdit_3_findId->text());
 210         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 211         tcpSocket->write(sendData.toUtf8().data());
 212     }
 213         break;
 214     case 11:{ // 备份数据库
 215         QString cmd = "databaseBack";
 216         QString data = "None";
 217         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 218         tcpSocket->write(sendData.toUtf8().data());
 219     }
 220         break;
 221     case 12:{ // 上传数据库
 222         QString cmd = "updateDatabase";
 223         QString data = QString("%1##%2").arg(upDateFileName).arg(upDateFileSize);
 224         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 225         tcpSocket->write(sendData.toUtf8().data());
 226     }
 227         break;
 228     case 20: {//发送退出程序信号
 229         QString cmd = "close";
 230         QString data = "None";
 231         QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data);
 232         tcpSocket->write(sendData.toUtf8().data());
 233         tcpSocket->disconnectFromHost(); //关闭tcp
 234         tcpSocket->close();
 235         QMainWindow::close();
 236     }
 237         break;
 238     default:
 239         break;
 240     }
 241 }
 242 
 243 //接收事件槽函数
 244 void MainWindow::dealReceiveData()
 245 {
 246     //接收的数据
 247     switch (callFunc) {
 248     case 1: {// 登陆获取信息
 249         QByteArray buf = tcpSocket->readAll();
 250         QString check = QString(buf);
 251         tcpSocket->disconnectFromHost(); //关闭tcp
 252         tcpSocket->close();
 253         if(check != "True")  // 登陆失败或连接错误
 254         {
 255             recCheck(check);
 256             return ;
 257         }
 258         //登陆成功
 259         showImage = 1;
 260         isLoad = true;
 261         ui->menuO->setEnabled(true);
 262         ui->stackedWidget->setCurrentWidget(ui->pageShowInfo);
 263 
 264     } break;
 265 
 266     case 2:{ //接收录制指纹1
 267         QByteArray buf = tcpSocket->readAll();
 268         QString check = QString(buf);
 269         if(check != "True")
 270         {
 271             recCheck(check);
 272             tcpSocket->disconnectFromHost(); //关闭tcp
 273             tcpSocket->close();
 274             break ;
 275         }
 276         ui->label_2_info->setText("请等待---");
 277         ui->label_2_info->show();
 278         ui->progressBar_2_fingerImage->show();
 279         callFunc = 20;
 280     } break;
 281 
 282     case 3:{ //接收录制指纹2
 283         QByteArray buf = tcpSocket->readAll();
 284         QString check = QString(buf);
 285         if(check != "True")
 286         {
 287             recCheck(check);
 288             tcpSocket->disconnectFromHost(); //关闭tcp
 289             tcpSocket->close();
 290             break ;
 291         }
 292         ui->label_2_info->setText("请等待---");
 293         ui->label_2_info->show();
 294         ui->progressBar_2_fingerImage->show();
 295         callFunc = 20;
 296     } break;
 297 
 298     case 4:{  //两次指纹对比度
 299         QByteArray buf = tcpSocket->readAll();
 300         QString str = QString(buf);
 301         //解析返回值
 302         QString check = QString(str).section("##", 0, 0);
 303         QString score = QString(str).section("##", 1, 1);
 304         tcpSocket->disconnectFromHost(); //关闭tcp
 305         tcpSocket->close();
 306 
 307         if("True" != check)
 308             return recCheck(check);
 309         //检验合格
 310         QMessageBox::information(this, "检验", QString("检验合格,分数:%1").arg(score));
 311         ui->pushButtonSure->setEnabled(true);
 312     } break;
 313 
 314     case 5:{  //存储
 315         QByteArray buf = tcpSocket->readAll();
 316         QString check = QString(buf);
 317         tcpSocket->disconnectFromHost(); //关闭tcp
 318         tcpSocket->close();
 319 
 320         if("True" != check)
 321             return recCheck(check);
 322         QMessageBox::information(this, "save", QString("储存成功!"));
 323 
 324         on_pushButtonConcel_clicked();
 325 
 326     } break;
 327 
 328     case 6:{  // 接收占用指纹资源是否成功
 329         QByteArray buf = tcpSocket->readAll();
 330         QString check = QString(buf);
 331         tcpSocket->disconnectFromHost(); //关闭tcp
 332         tcpSocket->close();
 333 
 334         if("True" != check)
 335             return recCheck(check);
 336         //开启后使能和显示提示
 337         ui->label_2_info->show();
 338         ui->label_2_info->setText("开启成功");
 339         ui->pushButtonSavefinger1->setEnabled(true);
 340         ui->pushButton_2_Start->setText("关闭");
 341     } break;
 342 
 343     case 7:{  // 接收释放指纹资源是否成功
 344         QByteArray buf = tcpSocket->readAll();
 345         QString check = QString(buf);
 346         tcpSocket->disconnectFromHost(); //关闭tcp
 347         tcpSocket->close();
 348 
 349         if("True" != check)
 350             return recCheck(check);
 351         QMessageBox::information(this, "release", QString("关闭成功!"));
 352         //关闭后隐藏和禁止button
 353         ui->label_2_info->hide();
 354         ui->progressBar_2_fingerImage->hide();
 355         ui->pushButton_2_Start->setText("开启");
 356 
 357     } break;
 358 
 359     case 8:{  // 获取接收log
 360         QByteArray buf = tcpSocket->readAll();
 361         QString check = QString(buf);
 362         if("True" != check){
 363             tcpSocket->disconnectFromHost(); //关闭tcp
 364             tcpSocket->close();
 365             return recCheck(check);
 366         }
 367         callFunc = 20;
 368 
 369     } break;
 370 
 371     case 9:{ // 查找人
 372         QByteArray buf = tcpSocket->readAll();
 373         QString check = QString(buf);
 374         if("True" != check){
 375             tcpSocket->disconnectFromHost(); //关闭tcp
 376             tcpSocket->close();
 377             return recCheck(check);
 378         }
 379         callFunc = 20;
 380     } break;
 381 
 382     case 10:{ // 删除人
 383         QByteArray buf = tcpSocket->readAll();
 384         QString check = QString(buf);
 385         if("True" != check){
 386             tcpSocket->disconnectFromHost(); //关闭tcp
 387             tcpSocket->close();
 388             return recCheck(check);
 389         }
 390         QMessageBox::information(this, "删除", QString("删除成功!"));
 391     } break;
 392 
 393     case 11:{ // 备份数据库
 394         QByteArray buf = tcpSocket->readAll();
 395         QString check = QString(buf);
 396         if("True" != check){
 397             tcpSocket->disconnectFromHost(); //关闭tcp
 398             tcpSocket->close();
 399             return recCheck(check);
 400         }
 401         callFunc = 20;
 402     } break;
 403 
 404     case 12:{  // 上传数据库
 405         QByteArray buf = tcpSocket->readAll();
 406         QString check = QString(buf);
 407         if("True" != check){
 408             tcpSocket->disconnectFromHost(); //关闭tcp
 409             tcpSocket->close();
 410             return recCheck(check);
 411         }
 412         qDebug() << buf;
 413         sendDataFile();
 414         //callFunc = 21;
 415     } break;
 416 
 417     case 20:{
 418         recData();
 419         //显示进度条
 420         switch (recWhat){
 421         case 1:{
 422             ui->progressBar_1_get->setValue((100 * recvSize) / fileSize);
 423         } break;
 424         case 2:{
 425             ui->progressBar_2_fingerImage->setValue((100 * recvSize) / fileSize);
 426         } break;
 427         case 3:{
 428             ui->progressBar_2_fingerImage->setValue((100 * recvSize) / fileSize);
 429         } break;
 430         case 4:{
 431         } break;
 432         case 5:{
 433             ui->progressBar_3_show->setValue((100 * recvSize) / fileSize);
 434         } break;
 435         default: break;
 436         }
 437         //传输完成后
 438         if(showInfo == true)
 439         {
 440             showInfo = false;
 441             callFunc = 0;
 442             QMessageBox::information(this, "完成", "接收完成");
 443             switch (recWhat) {
 444             case 1:{
 445                 recWhat = 0;
 446                 ui->pushButton_1_get->setEnabled(true);
 447                 ui->progressBar_1_get->hide();
 448             } break;
 449             case 2:{
 450                 ui->pushButtonSavefinger2->setEnabled(true);
 451                 showImage = 2;
 452                 update();
 453                 recWhat = 0;
 454             } break;
 455             case 3:{
 456                 ui->pushButtoncheckfinger->setEnabled(true);
 457                 showImage = 2;
 458                 update();
 459                 recWhat = 0;
 460             } break;
 461             case 4:{
 462                 ui->textEdit_3_show->clear();
 463                 QString str = showFile("find.txt");
 464                 ui->textEdit_3_show->append(str);
 465                 ui->pushButton_3_find->setEnabled(true);
 466                 ui->lineEdit_3_findId->setEnabled(true);
 467                 ui->pushButton_3_delect->setEnabled(true);
 468                 recWhat = 0;
 469             } break;
 470             case 5:{
 471                 ui->pushButton_3_back->setEnabled(true);
 472                 ui->progressBar_3_show->hide();
 473                 recWhat = 0;
 474             } break;
 475             default: break;
 476             }
 477         }
 478     } break;
 479 
 480 
 481     case 21:{ // 发送文件
 482         sendDataFile();
 483     } break;
 484 
 485 //    case 22:{ // 等待发送文件后的回应
 486 //        QByteArray buf = tcpSocket->readAll();;
 487 //        QString check = QString(buf).section("##", 0, 0);
 488 //        fileSize = QString(buf).section("##", 1, 1).toInt();
 489 //        if("True" != check){
 490 //            tcpSocket->disconnectFromHost(); //关闭tcp
 491 //            tcpSocket->close();
 492 //            return recCheck(check);
 493 //        }
 494 //        callFunc = 23;
 495 //    } break;
 496 
 497 //    case 23:{  //等待对方更新完成
 498 
 499 //    } break;
 500 
 501     default: break;
 502     }
 503 
 504 }
 505 
 506 //获取文件
 507 void MainWindow::recData()
 508 {
 509     QByteArray buf = tcpSocket->readAll();
 510     QString check = QString(buf);
 511 
 512     if(true == isStart)
 513     {
 514         qDebug() << buf;
 515         isStart = false;
 516         //解析传回的头文件
 517         fileName = QString(buf).section("##", 0, 0);
 518         fileSize = QString(buf).section("##", 1, 1).toInt();
 519         recvSize = 0;  //初始化接收数据大小
 520 
 521         qDebug() << fileName << fileSize;
 522         if (0 == fileSize){  // 文件大小为0
 523             tcpSocket->disconnectFromHost();
 524             tcpSocket->close();
 525             return recCheck("fileError");
 526         }
 527 
 528         fileTransport.setFileName(fileName);
 529 
 530         bool isOk = fileTransport.open(QIODevice::WriteOnly);
 531         if(false == isOk)
 532         {
 533             qDebug() << "WriteOnly error 40";
 534         }
 535         tcpSocket->write(QString("True").toUtf8().data());
 536 
 537 
 538     }
 539     else
 540     {
 541         qint64 len = fileTransport.write(buf);
 542         recvSize += len;
 543         if(recvSize == fileSize)  //判断是否传输完成
 544         {
 545             fileTransport.close();
 546             tcpSocket->disconnectFromHost();
 547             tcpSocket->close();
 548             //准备新的传输
 549             isStart = true;
 550             showInfo = true;
 551         }
 552     }
 553 }
 554 
 555 //发送文件
 556 void MainWindow::sendDataFile()
 557 {
 558     qint64 len = 0;
 559     do
 560     {
 561         //每次发送数据的大小
 562         char buf[4*1024] = {0};
 563         len = 0;
 564 
 565         //往文件中读数据
 566         len = fileTransport.read(buf, sizeof(buf));
 567 
 568         //发送数据,读多少,发多少
 569         len = tcpSocket->write(buf, len);
 570         //发送数据要累加
 571         sendSize += len;
 572         ui->progressBar_3_show->setValue(sendSize*100/upDateFileSize);
 573 
 574     }while(len >0 );
 575     //是否发送文件完毕
 576     if(sendSize == upDateFileSize)
 577     {
 578         QMessageBox::about(this, "传输", "文件发送完成");
 579         fileTransport.close();
 580 
 581         //把客户端关闭
 582         ui->textEdit_3_show->append("连接断开");
 583         tcpSocket->disconnectFromHost();
 584         tcpSocket->close();
 585 
 586 
 587         ui->pushButton_3_Updata->setEnabled(true);
 588         ui->pushButton_3_back->setEnabled(true);
 589         ui->menuO->setEnabled(true);
 590         ui->pushButton_3_find->setEnabled(true);
 591         ui->progressBar_3_show->setValue(0);
 592         ui->progressBar_3_show->hide();
 593         //callFunc = 22;
 594     }
 595 }
 596 
 597 //接收的信号做检测
 598 void MainWindow::recCheck(QString check)
 599 {
 600     qDebug() << check;
 601     if ("error" == check){// 连接失败或者是登陆失败
 602         if(false == isLoad)
 603             QMessageBox::warning(this, "连接信息", "用户名或者密码错误!");
 604         else
 605             QMessageBox::warning(this, "连接信息", "连接断开,重新登陆!");
 606         initData();
 607     }
 608     else if("102" == check){// 没有检测到手指
 609         ui->label_2_info->setText("请放入手指!");
 610         ui->label_2_info->show();
 611         switch (callFunc) {
 612         case 2:{
 613             ui->pushButtonSavefinger1->setEnabled(true);
 614         } break;
 615         case 3:{
 616             ui->pushButtonSavefinger2->setEnabled(true);
 617         }break;
 618         default: break;
 619         }
 620     }
 621     else if ("302" == check) { // 校验失败
 622         QMessageBox::warning(this, "校验信息", "两次指纹不匹配!");
 623         this->on_pushButtonConcel_clicked();
 624     }
 625     else if("link_error" == check) // 找不到服务器
 626     {
 627         QMessageBox::about(this, "连接信息", "连接失败......");
 628         initData();
 629     }
 630     else if("occupyError" == check) //抢占失败
 631     {
 632         QMessageBox::about(this, "占用信息", "设备正忙......");
 633         isOccupy = false;
 634     }
 635     else if("getLogError" == check)
 636     {
 637         QMessageBox::about(this, "获取日志", "失败!");
 638         ui->progressBar_1_get->hide();
 639         ui->pushButton_1_get->setEnabled(true);
 640     }
 641     else if("findError" == check)
 642     {
 643         QMessageBox::about(this, "查找", "失败!没这个人");
 644         ui->pushButton_3_find->setEnabled(true);
 645         ui->lineEdit_3_findId->setEnabled(true);
 646         ui->textEdit_3_show->clear();
 647     }
 648     else if("delectError" == check)
 649     {
 650         QMessageBox::about(this, "删除", "删除失败!");
 651     }
 652     else if("outPutError" == check)
 653     {
 654         QMessageBox::about(this, "导出数据库", "导出失败!");
 655         ui->pushButton_3_back->setEnabled(true);
 656     }
 657     else if("fileError" == check)
 658     {
 659         QMessageBox::about(this, "文件错误", "文件错误!");
 660     }
 661 }
 662 
 663 //绘图事件
 664 void MainWindow::paintEvent(QPaintEvent *)
 665 {
 666 
 667     QPainter p;
 668     //QPaintDevice pD;
 669     p.begin(this);//指定当前出窗口为绘图设备
 670 
 671     /* *
 672      * showImage
 673      * 1,显示页面颜色绘图
 674      * 2,指纹页面绘图
 675      * 3,查询页面绘图
 676      * */
 677     switch (showImage) {
 678     case 1:      
 679 //        ui->pageShowInfo->setStyleSheet("#pageShowInfo{"
 680 //                                       "border-image:url(:/image/image/car.jpg);"
 681 //                                       "}"
 682 //                                       );
 683 //        break;
 684 
 685     case 2:{
 686         QString str = QString("QWidget{"
 687                       "border-image:url(finger.bmp);"
 688                       "}");
 689         ui->widgetFinger->setStyleSheet(str);
 690     }
 691         break;
 692 
 693     case 3:
 694 
 695         break;
 696 
 697     default:
 698         break;
 699     }
 700 
 701     p.end();
 702 }
 703 
 704 //显示文本
 705 QString MainWindow::showFile(QString fileName)
 706 {
 707     QFile file(fileName);
 708     ui->textEdit_1_Show->clear();
 709     bool isOk = file.open(QIODevice::ReadOnly);
 710     if(false == isOk)
 711     {
 712         qDebug() << "WriteOnly error 40";
 713     }
 714     QByteArray buff = file.readAll();
 715     QString str = QString(buff);
 716     return str;
 717 }
 718 /***================= 菜单函数 ===================***/
 719 //显示界面
 720 void MainWindow::on_actionShow_triggered()
 721 {
 722     ui->stackedWidget->setCurrentWidget(ui->pageShowInfo);
 723     showImage = 1;
 724     update();
 725 
 726 }
 727 
 728 //录指纹界面
 729 void MainWindow::on_actionSave_triggered()
 730 {
 731     ui->stackedWidget->setCurrentWidget(ui->pageSave);
 732     showImage = 2;
 733     update();
 734 }
 735 
 736 //查找界面
 737 void MainWindow::on_actionFind_triggered()
 738 {
 739     ui->stackedWidget->setCurrentWidget(ui->pageFind);
 740     showImage = 3;
 741     update();
 742 }
 743 
 744 //菜单栏退出
 745 void MainWindow::on_actionClose_triggered()
 746 {
 747     /***********连接服务器发送数据***********/
 748     callFunc = 20;
 749     bool check = tcpLink(1);    //不要默认模式 0
 750     if(false == check)
 751     {
 752         MainWindow::close();
 753     }
 754 }
 755 
 756 /*** ===================界面登陆的函数========================== ***/
 757 //登陆函数
 758 void MainWindow::on_pushButtonReg_clicked()
 759 {
 760     //禁止输入
 761     ui->lineEditUserName->setEnabled(false);
 762     ui->lineEditPassward->setEnabled(false);
 763 
 764     tcpSocket->disconnectFromHost();
 765     tcpSocket->close();
 766     //连接服务器
 767     callFunc = 1;
 768     tcpLink();  //默认模式 0
 769 
 770 }
 771 
 772 
 773 //退出函数
 774 void MainWindow::on_pushButtonClose_clicked()
 775 {
 776     QMainWindow::close();
 777 }
 778 
 779 //改变连接端口
 780 void MainWindow::on_pB_logoChangelink_clicked()
 781 {
 782     if(false == isChangeLink)
 783     {
 784         isChangeLink = true;
 785         ui->pB_logoChangelink->setText("返回?");
 786         //清楚编辑行文本
 787         ui->lineEditUserName->clear();
 788         ui->lineEditPassward->clear();
 789         //设置端口和ip
 790         ui->label_logo_name->setText("ip :");
 791         ui->label_logo_passwd->setText("port :");
 792         ui->lineEditPassward->setEchoMode(QLineEdit::Normal);  //设置正常显示
 793         //隐藏登陆
 794         ui->pushButtonReg->hide();
 795 
 796         qDebug() << ip << port;
 797     }
 798     else
 799     {
 800         isChangeLink = false;
 801         ui->pB_logoChangelink->setText("更改登陆连接?");
 802         //设置端口和ip
 803         ip = ui->lineEditUserName->text();
 804         port = ui->lineEditPassward->text().toInt();
 805         //清楚编辑行文本
 806         ui->lineEditUserName->clear();
 807         ui->lineEditPassward->clear();
 808         //设置为登陆模式
 809         ui->label_logo_name->setText("用户名:");
 810         ui->label_logo_passwd->setText("密 码:");
 811         ui->lineEditPassward->setEchoMode(QLineEdit::Password);
 812         //显示登陆
 813         ui->pushButtonReg->show();
 814 
 815         qDebug() << ip << port;
 816     }
 817 }
 818 /*** ===================界面1的函数========================== */
 819 //在窗口显示信息
 820 void MainWindow::on_pushButton_1_show_clicked()
 821 {
 822     QString str = showFile("log.txt");
 823     ui->textEdit_1_Show->append(str);
 824 }
 825 //下载更新log
 826 void MainWindow::on_pushButton_1_get_clicked()
 827 {
 828     ui->pushButton_1_get->setEnabled(false);
 829     //显示进度条
 830     ui->progressBar_1_get->setValue(0);
 831     ui->progressBar_1_get->show();
 832     /***********连接服务器发送数据***********/
 833     recWhat = 1;
 834     callFunc = 8;
 835     tcpLink();  //默认模式 0
 836 }
 837 /*** ===================界面2的函数========================== */
 838 //开启录制,占用资源
 839 void MainWindow::on_pushButton_2_Start_clicked()
 840 {
 841     if(false == isOccupy)  //开启占用
 842     {
 843         isOccupy = true;
 844         /***********连接服务器发送数据***********/
 845         callFunc = 6;
 846         //tcp连接
 847         tcpLink();
 848     }
 849     else  // 释放
 850     {
 851         isOccupy = false;
 852         //禁止button
 853         ui->pushButtonSavefinger1->setEnabled(false);
 854         ui->pushButtonConcel->setEnabled(false);
 855         ui->pushButtonSavefinger2->setEnabled(false);
 856         ui->pushButtonSure->setEnabled(false);
 857         ui->pushButtoncheckfinger->setEnabled(false);
 858         //隐藏进度条
 859         ui->progressBar_2_fingerImage->setValue(0);
 860         ui->progressBar_2_fingerImage->hide();
 861         /***********连接服务器发送数据***********/
 862         callFunc = 7;
 863         //tcp连接
 864         tcpLink();
 865     }
 866 }
 867 
 868 //录制指纹 1 Button
 869 void MainWindow::on_pushButtonSavefinger1_clicked()
 870 {
 871     //使能返回button和禁止录制button
 872     ui->pushButtonSavefinger1->setEnabled(false);
 873     ui->pushButtonConcel->setEnabled(true);
 874     //禁止输入
 875     ui->lineEditname->setEnabled(false);
 876     ui->lineEditID->setEnabled(false);
 877     ui->lineEditdate->setEnabled(false);
 878     //隐藏进度条
 879     ui->progressBar_2_fingerImage->setValue(0);
 880     ui->progressBar_2_fingerImage->hide();
 881     /***********连接服务器发送数据***********/
 882     callFunc = 2;
 883     recWhat = 2;
 884     tcpLink();  //默认模式 0
 885 
 886 }
 887 
 888 //录制指纹 2 Button
 889 void MainWindow::on_pushButtonSavefinger2_clicked()
 890 {
 891     //禁止button
 892     ui->pushButtonSavefinger2->setEnabled(false);
 893     //隐藏进度条
 894     ui->progressBar_2_fingerImage->setValue(0);
 895     ui->progressBar_2_fingerImage->hide();
 896     /***********连接服务器发送数据***********/
 897     callFunc = 3;
 898     recWhat = 3;
 899     tcpLink();  //默认模式 0
 900 
 901 
 902 }
 903 
 904 //检验两次录取准确度
 905 void MainWindow::on_pushButtoncheckfinger_clicked()
 906 {
 907     ui->pushButtoncheckfinger->setEnabled(false);
 908     /***********连接服务器发送数据***********/
 909     callFunc = 4;    
 910     tcpLink();  //默认模式 0
 911 }
 912 
 913 
 914 //取消录取操作
 915 void MainWindow::on_pushButtonConcel_clicked()
 916 {
 917     //开启输入
 918     ui->lineEditname->setEnabled(true);
 919     ui->lineEditID->setEnabled(true);
 920     ui->lineEditdate->setEnabled(true);
 921     //button功能转换
 922     ui->pushButtonSavefinger1->setEnabled(true);
 923     ui->pushButtonConcel->setEnabled(false);
 924     ui->pushButtonSavefinger2->setEnabled(false);
 925     ui->pushButtonSure->setEnabled(false);
 926     //隐藏显示信息
 927     ui->label_2_info->hide();
 928     ui->progressBar_2_fingerImage->hide();
 929     //关闭连接主机
 930     tcpSocket->disconnectFromHost();
 931     tcpSocket->close();
 932     //关闭文件
 933     fileTransport.close();
 934     isStart = true;
 935     showInfo = false;
 936 }
 937 
 938 //更新数据库
 939 void MainWindow::on_pushButtonSure_clicked()
 940 {
 941     ui->pushButtonSure->setEnabled(false);
 942     //弹出对话框提醒用户是否更新
 943     QString str = "是否跟新到数据库";
 944     int isOk = QMessageBox::information(this, "issave", str, QMessageBox::Ok, QMessageBox::Cancel);
 945 
 946     if (QMessageBox::Cancel == isOk)
 947     {
 948         on_pushButtonConcel_clicked();
 949         return;
 950     }
 951 
 952 //    /*================== 数据库的操作 ==============*/
 953 //    //添加MySql数据库
 954 //    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
 955 //    //连接数据库
 956 //    db.setHostName("127.0.0.1"); //数据库服务器IP
 957 //    db.setUserName("root"); //数据库用户名
 958 //    db.setPassword("123456"); //密码
 959 //    db.setDatabaseName("myinfo"); //使用哪个数据库
 960 
 961 //    //打开数据库
 962 //    if(false == db.open()) //数据库打开失败
 963 //    {
 964 //        QMessageBox::warning(this, "错误", db.lastError().text());
 965 //        return;
 966 
 967 //    }
 968 
 969 //    db.close();
 970     callFunc = 5;
 971     tcpLink();  //默认模式 0
 972 
 973 }
 974 
 975 /*** ===================界面3的函数========================== */
 976 //查找人
 977 void MainWindow::on_pushButton_3_find_clicked()
 978 {
 979     ui->pushButton_3_find->setEnabled(false);
 980     ui->lineEdit_3_findId->setEnabled(false);
 981     /***********连接服务器发送数据***********/
 982     callFunc = 9;
 983     recWhat = 4;
 984     tcpLink();  //默认模式 0
 985 }
 986 
 987 //删除信息
 988 void MainWindow::on_pushButton_3_delect_clicked()
 989 {
 990     ui->pushButton_3_delect->setEnabled(false);
 991     /***********连接服务器发送数据***********/
 992     callFunc = 10;
 993     tcpLink();  //默认模式 0
 994 }
 995 //输入框变化
 996 void MainWindow::on_lineEdit_3_findId_textChanged(const QString &arg1)
 997 {
 998     ui->pushButton_3_delect->setEnabled(false);
 999 }
1000 
1001 //备份数据库
1002 void MainWindow::on_pushButton_3_back_clicked()
1003 {
1004     ui->pushButton_3_back->setEnabled(false);
1005     ui->progressBar_3_show->setValue(0);
1006     ui->progressBar_3_show->show();
1007     /***********连接服务器发送数据***********/
1008     callFunc = 11;
1009     recWhat = 5;
1010     tcpLink();  //默认模式 0
1011 
1012 }
1013 //按查找的名字
1014 void MainWindow::on_pushButton_3_findName_clicked()
1015 {
1016     ui->lineEdit_3_findId->setEnabled(true);
1017     QString txt = ui->pushButton_3_findName->text();
1018     if("查找id:" == txt)
1019     {
1020         ui->pushButton_3_findName->setText("查找name:");
1021         findWhat = "name";
1022     }
1023     else if("查找name:" == txt)
1024     {
1025         ui->pushButton_3_findName->setText("查找date:");
1026         findWhat = "time";
1027     }
1028     else if("查找date:" == txt)
1029     {
1030         ui->pushButton_3_findName->setText("查找all:");
1031         findWhat = "id";
1032 //        ui->lineEdit_3_findId->setEnabled(false);
1033     }
1034 //    else if("查找all:" == txt)
1035 //    {
1036 //        ui->pushButton_3_findName->setText("查找id:");
1037 //        findWhat = "id";
1038 //    }
1039 }
1040 
1041 //上传.sql 文件 并更新模块
1042 void MainWindow::on_pushButton_3_Updata_clicked()
1043 {
1044     QString filePath = QFileDialog::getOpenFileName(this, "open", "./");
1045     //如果路径有效
1046     if(false == filePath.isEmpty()){
1047         upDateFileName.clear(); // 上传文件名字
1048         upDateFileSize = 0;//文件大小
1049         sendSize = 0; // 发送文件的大小
1050         //获取信息
1051         QFileInfo info(filePath);
1052         upDateFileName = info.fileName();
1053         upDateFileSize = info.size();
1054 
1055         //打开文件
1056         fileTransport.setFileName(filePath);
1057         bool isOk = fileTransport.open(QIODevice::ReadOnly);
1058         if(false == isOk){
1059             qDebug() << "打开失败 62";
1060         }
1061 
1062         ui->textEdit_3_show->setText(filePath);
1063 
1064         ui->pushButton_3_Updata->setEnabled(false);
1065         ui->pushButton_3_back->setEnabled(false);
1066         ui->menuO->setEnabled(false);
1067         ui->pushButton_3_delect->setEnabled(false);
1068         ui->pushButton_3_find->setEnabled(false);
1069         ui->progressBar_3_show->setValue(0);
1070         ui->progressBar_3_show->show();
1071 
1072     }
1073     else{
1074         qDebug() << "选择文件路径出错 62";
1075 
1076 
1077     }
1078 
1079 
1080     /***********连接服务器发送数据***********/
1081     callFunc = 12;
1082     recWhat = 6;
1083     tcpLink();  //默认模式 0
1084 }
Qt客户端  .cpp文件

 

  1 #ifndef MAINWINDOW_H
  2 #define MAINWINDOW_H
  3 
  4 #include <QMainWindow>
  5 #include "QTcpServer"
  6 #include "QTcpSocket"
  7 #include "QPaintEvent"
  8 
  9 namespace Ui {
 10 class MainWindow;
 11 }
 12 
 13 class MainWindow : public QMainWindow
 14 {
 15     Q_OBJECT
 16 
 17 public:
 18     explicit MainWindow(QWidget *parent = 0);
 19     ~MainWindow();
 20 
 21     //初始化数据
 22     void initData();
 23     //初始化tcp
 24     void initTcp();
 25     //设置tcp连接
 26     bool tcpLink(int mode = 0);
 27 
 28     //发送数据给服务器
 29     void sendDataToServe();
 30     //处理接收的数据
 31     void dealReceiveData();
 32     //接收文件
 33     void recData();
 34     //处理接收的返回值检测
 35     void recCheck(QString check);
 36     //画图事件
 37     void paintEvent(QPaintEvent *);
 38     //显示文本
 39     QString showFile(QString fileName);
 40     //发送文件
 41     void sendDataFile();
 42 
 43 signals:
 44     void connectSuccess();
 45 
 46 private slots:
 47     //菜单显示事件
 48     void on_actionShow_triggered();
 49 
 50     void on_actionSave_triggered();
 51 
 52     void on_actionFind_triggered();
 53 
 54     void on_actionClose_triggered();  // 菜单退出
 55 
 56     //button事件
 57     void on_pushButtonSavefinger1_clicked(); //录指纹1
 58 
 59     void on_pushButtonConcel_clicked(); //取消录指纹
 60 
 61     void on_pushButtonSure_clicked(); //确定录取
 62 
 63     void on_pushButtonReg_clicked(); //登陆服务器
 64 
 65     void on_pushButtonClose_clicked(); //关闭窗口
 66 
 67     void on_pushButtonSavefinger2_clicked(); //录制指纹 2
 68 
 69     void on_pushButtoncheckfinger_clicked(); //检验两次录取准确度
 70 
 71     void on_pB_logoChangelink_clicked();  // 登陆界面改变link
 72 
 73     void on_pushButton_2_Start_clicked();  //申请资源
 74 
 75     void on_pushButton_1_get_clicked();   //获取日志
 76 
 77     void on_pushButton_1_show_clicked();  //显示日志
 78 
 79     void on_pushButton_3_find_clicked();  //查找人
 80 
 81     void on_lineEdit_3_findId_textChanged(const QString &arg1);
 82 
 83     void on_pushButton_3_delect_clicked(); //删除信息
 84 
 85     void on_pushButton_3_back_clicked(); //备份数据库
 86 
 87     void on_pushButton_3_findName_clicked();  // 更改查找选项
 88 
 89     void on_pushButton_3_Updata_clicked();  // 上传数据库
 90 
 91 private:
 92     Ui::MainWindow *ui;
 93 
 94     //tcp套接字指针
 95     QTcpSocket *tcpSocket;
 96     QString ip;
 97     quint16 port;
 98 
 99     int showImage; //显示哪个界面
100     bool isLoad; //是否登陆
101     bool isChangeLink;
102     int recWhat; //接收的什么数据
103     bool isOccupy; //是否占用指纹资源
104     /* *
105      * 哪个函数发送的tcp请求
106      * 1,登陆
107      * */
108     int callFunc;
109 
110     QString filePath; //文件路径
111     QFile fileTransport;//文件对象
112     QString fileName;//文件名字
113     qint64 fileSize;//文件大小
114     qint64 recvSize;//已经发送的文件的大小
115     bool isStart;  //接收头文件
116     bool showInfo; //接收完成后
117 
118     QString upDateFileName; // 上传文件名字
119     qint64 upDateFileSize;//文件大小
120     qint64 sendSize; // 发送文件的大小
121 
122     QString findWhat; //按什么查找数据库
123 };
124 
125 #endif // MAINWINDOW_H
客户端头文件 .h

 

3.然后就是数据库储存了

 就是一些简单的mysql语句

  1 #!/usr/local/opt/python-3.5.2/bin/python3.5
  2 #-*- coding:utf8 -*-
  3 
  4 import pymysql
  5 import os, sys
  6 import configparser
  7 
  8 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  9 sys.path.append(PATH)
 10 
 11 from core import dealFile
 12 
 13 
 14 class mySqlDeal:
 15     """数据库的操作"""
 16     def __init__(self, cmd=None, data=None, host="127.0.0.1", port=3306, user="root", passwd="123456", db="finger", table="test"):
 17         cf = configparser.ConfigParser()
 18         cf = dealFile.readConf(cf)
 19         host = cf.get("db", "db_host")
 20         port = cf.getint("db", "db_port")
 21         user = cf.get("db", "db_user")
 22         passwd = cf.get("db", "db_pwd")
 23         db = cf.get("db", "db_database")
 24         table = cf.get("db", "db_table")
 25         """初始化数据"""
 26         self.cmd = cmd
 27         self.data = data
 28         self.host = host
 29         self.port = port
 30         self.user = user
 31         self.passwd = passwd
 32         self.db = db
 33         self.table = table
 34         pass
 35 
 36     def link(self):
 37         """连接数据库"""
 38         self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.db)
 39         self.cursor = self.conn.cursor()
 40         pass
 41 
 42     def run(self, cmd=None, table=None):
 43         """执行cmd"""
 44         self.link()
 45         if hasattr(self, self.cmd):
 46             func = getattr(self, self.cmd)
 47             return func(data=self.data, table=self.table)
 48         self.endSql()
 49         return False, None
 50 
 51     def creatDatabase(self, data, table):
 52         """创建数据库"""
 53         pass
 54 
 55     def creatTable(self, data, table):
 56         """创建表"""
 57         pass
 58 
 59     def insertData(self, data, table):
 60         """插入数据到数据库"""
 61         if isinstance(data, dict) is not True:   # 判断data是不是字典类型
 62             return False, None
 63         # 拼接sql语句  执行
 64         sqlStr = "INSERT INTO {table} VALUES ('{num}', '{id}', '{name}', '{date}', '{finger}');"\
 65             .format(table=table, num=data['num'], id=data["id"], name=data["name"], date=data["date"], finger=data["finger"])
 66         self.cursor.execute(sqlStr)
 67 
 68         self.endSql()  # 结束sql
 69         return True, None
 70         pass
 71 
 72     def selectAll(self, data=None, table=None):
 73         """选择数据库中的数据  所有"""
 74         # 拼接sql语句  执行
 75         sqlStr = "SELECT * FROM {table};".format(table=table)
 76         self.cursor.execute(sqlStr)
 77         data = self.cursor.fetchall()   # 寻找所有数据
 78 
 79         self.endSql()   # 结束sql
 80         return True, data
 81         pass
 82 
 83     def selectData(self, data=None, table=None):
 84         """选择数据库中的数据"""
 85         # 拼接sql语句  执行
 86         data = data.split(":")
 87         sqlStr = "SELECT * FROM {table} WHERE {what}={find};".format(table=table, what=data[0], find=data[1])
 88         self.cursor.execute(sqlStr)
 89         data = self.cursor.fetchall()   # 寻找所有数据
 90 
 91         self.endSql()   # 结束sql
 92         return True, data
 93         pass
 94 
 95     def selectId(self, data, table):
 96         """
 97         :param data: 固定格式必须要  what:find
 98         :param table:
 99         :return:
100         """
101         # 拼接sql语句  执行
102         data = data.split(":")
103         if data[0] == "all":
104             sqlStr = "SELECT id, name, time FROM {table};".format(table=table)
105         else:
106             sqlStr = "SELECT id, name, time FROM {table} WHERE {what} REGEXP '^{find}';"\
107                 .format(table=table, what=data[0], find=data[1])
108         self.cursor.execute(sqlStr)
109         data = self.cursor.fetchall()   # 寻找所有数据
110         self.endSql()  # 结束sql
111         if len(data) is 0:
112             return False, None
113         return True, data
114 
115     def selectNum(self, data, table):
116         data = data.split(":")
117         sqlStr = "SELECT num FROM {table} WHERE {what} REGEXP '^{find}';"\
118             .format(table=table, what=data[0], find=data[1])
119         self.cursor.execute(sqlStr)
120         data = self.cursor.fetchall()  # 寻找所有数据
121         self.endSql()  # 结束sql
122         if len(data) is 0:
123             return False, None
124         return True, data
125         pass
126 
127     def delectId(self, data, table):
128         """
129         :param data: 固定格式必须要  what:find
130         :param table:
131         :return:
132         """
133         # 拼接sql语句  执行
134         data = data.split(":")
135         if data[0] == "all":
136             sqlStr = "DELETE FROM {table};".format(table=table)
137         else:
138             sqlStr = "DELETE FROM {table} WHERE {what} REGEXP '^{find}';".format(table=table, what=data[0], find=data[1])
139         self.cursor.execute(sqlStr)
140         self.endSql()  # 结束sql
141         return True, None
142 
143     def endSql(self):
144 
145         """提交和关闭sql"""
146         self.conn.commit()
147         self.cursor.close()
148         self.conn.close()
149 
150     pass
151 
152 
153 if __name__ == "__main__":
154     # delectId
155     # A = mySqlDeal("selectWhat", "name")
156     A = mySqlDeal("selectId", "name:12")
157     check, data = A.run()
158     # print(check)
159     # for i in data:
160     #     print(i)
161     print(check)
162     print(data)
163 
164     pass
dealSql.py

 

 4.可以用Pycharm远程调试树莓派啦

 网上有很多远程调试的例子,如果还是不会可以留言

首先用编写打卡的程序,用到树莓派GPIO口

  1 # -*- coding:utf8 -*-
  2 
  3 import RPi.GPIO as GPIO
  4 
  5 import os,sys
  6 
  7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  8 sys.path.append(PATH)
  9 # import core
 10 from core.dealSql import mySqlDeal
 11 from core import dealFinger
 12 # from core import clockIn
 13 from core import dealFile
 14 from core import oledshow
 15 # from core import Tcpserver
 16 import time
 17 
 18 isOccupy = False
 19 
 20 class ClockCheck:
 21 
 22     def __init__(self, queueOled, queueToTcp, queueToClock, queueIsNewSql):
 23         self.flage = False
 24         self.queueOled = queueOled
 25         self.queueToTcp = queueToTcp
 26         self.queueToClock = queueToClock
 27         self.queueIsNewSql = queueIsNewSql
 28         """初始化GPIO"""
 29         self.GPIO_Pin = 18
 30         GPIO.setmode(GPIO.BCM)
 31         GPIO.setwarnings(False)
 32         GPIO.setup(self.GPIO_Pin, GPIO.IN)
 33         """引入其他模块"""
 34         # self.mysql = mySqlDeal()
 35         self.myFinger = dealFinger.DealFinger()
 36         self.check = 0
 37 
 38         # check, self.data = self.mysql.run()
 39         pass
 40 
 41     def run(self):
 42         while True:
 43             """判断是否串口可用"""
 44             check = self.isOk()
 45             if check is not True:
 46                 continue
 47             """获取数据库的值"""
 48             self.flage = True
 49 
 50             a = time.time()
 51             check = self.getChar()  # 判断是否获取成功
 52             if check is not True:
 53                 print(check)
 54                 self.release()
 55                 continue
 56             """判断是否有指纹存在"""
 57             check = self.checkFinger(0)
 58             self.release()
 59             print(time.time() - a)
 60             if check is not True:
 61                 print("ERROR")
 62                 continue
 63             print("success!")
 64         pass
 65 
 66     def isOk(self):
 67         """判断是否串口可用"""
 68         if GPIO.input(self.GPIO_Pin) is GPIO.LOW:
 69             if self.queueIsNewSql.empty() is not True:  # 是否跟新数据
 70                 self.queueIsNewSql.get()
 71                 self.renewData()
 72             """判断是否有指纹按下"""
 73             if self.flage is True:
 74                 self.flage = False
 75             return False
 76         """有指纹按下判断是否可抢占"""
 77         check = self.occupy()
 78         if check is not True:
 79             return False
 80 
 81         if self.check is 102:  # 清除没指纹意外
 82             self.check = 0
 83             self.flage = False
 84         if self.flage is not False:
 85             self.release()  # 释放
 86             return False
 87         return True
 88         pass
 89 
 90     def occupy(self):
 91         """抢占指纹资源"""
 92         global isOccupy
 93         if self.queueToClock.empty() is not True:
 94             isOccupy = self.queueToClock.get()
 95 
 96         if isOccupy is True:
 97             # print("occupyError")
 98             return False
 99         self.queueToTcp.put(1)
100         return True
101         pass
102 
103     def release(self):
104         """释放指纹资源"""
105         self.queueToTcp.put(0)
106 
107     def renewData(self):
108         # check, self.data = self.mysql.run()
109         # return check
110         pass
111 
112     def checkFinger(self, data):
113         """和数据库中的指纹匹配"""
114         self.myFinger.link()
115         check, buff = self.myFinger.checkPSIdentify()
116         if check is True:
117             """获取数据库中的相应值"""
118             num = buff[1]*256 + buff[2]
119             numStr = "num:%s" % num
120             print(numStr)
121             mysql = mySqlDeal("selectData", numStr)
122             check, data = mysql.run()
123             for i in data:
124                 fingerData = eval(i[4])
125                 fingerData = dealFinger.DealBuff(fingerData)
126                 fingerData = fingerData.write()
127                 check, score = self.myFinger.isFinger(fingerData)
128                 if check is True:
129                     self.writeLog(i[1] + " " + i[2], "log.txt")
130                     qDir ={
131                         "check": True,
132                         "id": i[1],
133                         "name": i[2]
134                     }
135                     self.queueOled.put(qDir)
136                     time.sleep(0.2)
137                     return True
138         print(check)
139         qDir = {
140             "check": False
141         }
142         self.queueOled.put(qDir)
143         time.sleep(0.2)
144         return False
145 
146     def writeLog(self, data, fileName):
147         date = time.strftime("%Y-%m-%d %X  ")
148         data = date + data + "\r\n\r\n"
149         dealFile.textLog(data, fileName)
150         pass
151 
152     def getChar(self):
153         """获取现在按下的指纹的信息"""
154         self.myFinger.link()
155         check = self.myFinger.getImage()  # 检测获取图像
156         if check is not True:
157             self.check = check
158             return check
159 
160         self.myFinger.link()
161         check = self.myFinger.genChar("1")  # 检测生成特征值 放如模块1
162         if check is not True:
163             return check
164 
165         return True
166     pass
167 
168 
169 if __name__ == "__main__":
170     import core
171     A = ClockCheck(core.qOledClock, core.qToTcpOccupy, core.qToClockOccupy, core.qIsNewSql)
172     A.run()
173     pass
clockIn.py

 

当能够正常打卡后就需要在液晶屏上显示了

 1 import time
 2 import Adafruit_GPIO.SPI as SPI
 3 import Adafruit_SSD1306
 4 from PIL import Image, ImageDraw, ImageFont
 5 
 6 import os, sys
 7 
 8 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 9 sys.path.append(PATH)
10 
11 path = PATH + "/static/"
12 
13 # 引脚配置,按照上面的接线来配置
14 RST = 17
15 DC = 27
16 # 因为连的是CE0,这里的PORT和DEVICE也设置为0
17 SPI_PORT = 0
18 SPI_DEVICE = 0
19 disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
20 class Oled:
21     """oled显示"""
22     def __init__(self, queue):
23         self.queue = queue
24         # 根据自己的oled型号进行初始化,我的是128X64、SPI的oled,使用SSD1306_128_64初始化
25         self.disp = disp
26         self.disp.begin()
27         self.disp.clear()
28         self.disp.display()
29         self.width = self.disp.width
30         self.height = self.disp.height
31         # image ,显示一些文字
32         self.image = Image.new('1', (self.width, self.height))
33         self.draw = ImageDraw.Draw(self.image)
34 
35         self.fontDate = ImageFont.truetype(path + "simsun.ttc", 16)
36         self.fontTime = ImageFont.truetype(path + "EXEPixelPerfect.ttf", 50)
37         self.fontNum = ImageFont.truetype(path + "EXEPixelPerfect.ttf", 35)
38         self.fontName = ImageFont.truetype(path + "simsun.ttc", 28)
39         pass
40 
41     def run(self):
42         """显示界面"""
43         while True:
44             date = time.ctime()
45             date = date.split(" ")
46             num = len(date)   # 当日期小于10时  日期为" num"  大于10为"num"
47             self.draw.text((0, 0), date[0], font=self.fontDate, fill=1)  # 星期几
48             if num == 6:
49                 self.draw.text((80, 0), date[1] + " " + date[3], font=self.fontDate, fill=1)  # 月份
50             else:
51                 self.draw.text((80, 0), date[1] + " " + date[2], font=self.fontDate, fill=1)  # 月份
52             self.draw.text((0, 20), date[-2], font=self.fontTime, fill=1)    # 时间
53             """显示"""
54             self.disp.image(self.image)
55             self.disp.display()
56             """清屏"""
57             self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
58             """显示"""
59             self.showPeple()
60 
61             pass
62 
63     def showPeple(self):
64         """显示人"""
65         if self.queue.empty() is True:  # 没有人按
66             # time.sleep(0.2)
67             return
68         data = self.queue.get()
69         if data["check"] is False:    # 有人按匹配错误
70             self.draw.text((15, 20), "ERROR", font=self.fontTime, fill=1)
71             """显示"""
72             self.disp.image(self.image)
73             self.disp.display()
74             """清屏"""
75             self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
76             time.sleep(2)
77             return
78         self.draw.text((0, 0), data["id"], font=self.fontNum, fill=1)
79         self.draw.text((25, 30), data["name"], font=self.fontName, fill=1)
80         """显示"""
81         self.disp.image(self.image)
82         self.disp.display()
83         """清屏"""
84         self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
85         time.sleep(2)
86         pass
87 
88     pass
89 
90 
91 if __name__ == "__main__":
92     from multiprocessing import Queue
93     q = Queue()
94     A = Oled(q)
95     A.run()
oledshow.py

 

 

5.怎么实现物联呢

这就要用到公网平台了,应为我们都是“私网”,

刚开始想用yeelink的,但是发现好像没人维护用不了了,我就发现了“乐为物联”这个平台,操作简单

你首先得在上面注册一个用户,他上面有api的介绍,很容易看懂

再分享一波

我是想在微信上发送命令

  1 # -*- coding:utf8 -*-
  2 
  3 import configparser
  4 from core import dealFile
  5 from core import emailSendReceive
  6 
  7 import optparse
  8 import os, sys
  9 import socket
 10 import json,re
 11 import time
 12 
 13 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 14 sys.path.append(PATH)
 15 
 16 cf = configparser.ConfigParser()
 17 cf = dealFile.readConf(cf)
 18 ip = cf.get("lewei", "ip")
 19 port = cf.getint("lewei", "port")
 20 userKey = cf.get("lewei", "userKey")
 21 gatewayNode = cf.get("lewei", "gatewayNode")
 22 
 23 
 24 # ip = "tcp.lewei50.com"
 25 # port = 9960
 26 # userKey = "9701daf039574b199602b4958252dc19"
 27 # gatewayNode = "02"
 28 
 29 head = "&^!"
 30 
 31 class ClientHandler():
 32 
 33     def __init__(self):
 34 
 35         self.bufsize = 1024
 36         # self.op = optparse.OptionParser()
 37         # option,args = self.op.parse_args()
 38         #
 39         # self.verify_args(option,args)
 40         self.connect()
 41 
 42     def verify_args(self,option,args):
 43         '启动命令处理'
 44         cmd = args[0]
 45         if hasattr(self,cmd):
 46             func = getattr(self,cmd)
 47             func()
 48         else:
 49             exit("No parameter")
 50 
 51     def connect(self):
 52         '连接网路'
 53         self.loadToServer()
 54         oldTime = time.time()
 55         while True:
 56             nowTime = time.time()
 57             if nowTime - oldTime > 40:
 58                 oldTime = nowTime
 59                 self.loadToServer()
 60             self.interactive()
 61 
 62     def interactive(self):
 63         self.rev_deal()
 64 
 65     def loadToServer(self):
 66         '发送数据登陆服务器'
 67         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 68         self.sock.connect((ip, port))
 69         cmd={
 70             'method': "update",
 71             'gatewayNo': gatewayNode,
 72             'userkey': userKey
 73         }
 74         self.sendData(cmd)
 75 
 76     def rev_deal(self):
 77         '处理接收的数据做命令分类'
 78         """调用该命令时会调用该设备的API地址传递参数f=方法名,p1=参数1,p2=参数2......"""
 79         data = self.sock.recv(self.bufsize).decode("gbk")
 80         if data:
 81             print(data)
 82             data = re.split("[&^!]", data) # 去掉数据尾巴
 83             data = eval(data[0]) # 转换成字典
 84             self.data = data
 85             # print(data)
 86             if hasattr(self, data["f"]):
 87                 func = getattr(self, data["f"])
 88                 func()
 89 
 90     """=======================================  f = message  ==========================================="""
 91     def message(self):
 92         print("message")
 93         pass
 94 
 95     """=======================================  f = sendemail  ==========================================="""
 96     def sendEmail(self):
 97         data = str.lower(self.data["p1"])
 98         if data:
 99             if hasattr(self, data):
100                 func = getattr(self, data)
101                 func()
102         self.sendSuccess()
103         pass
104 
105     def getlog(self):
106         """得到日志"""
107         a = emailSendReceive.SendEmail()
108         a.run(self.data["p1"])
109         self.sendSuccess()
110         pass
111 
112     def backlog(self):
113         """备份日志"""
114         backname = "log_{date}.txt".format(date=time.strftime("%Y.%m.%d.%X"))
115         dealFile.backFile("log.txt", backname)
116         pass
117 
118     def getlogall(self):
119         """得到所有日志"""
120         a = emailSendReceive.SendEmail()
121         a.run(self.data["p1"])
122         self.sendSuccess()
123         pass
124 
125     def clean(self):
126         """清除所有日志"""
127         dealFile.cleanFile()  # 清除日志
128         pass
129 
130     """=======================================  f = getAllSensors  ==========================================="""
131     def getAllSensors(self):
132         '上传传感器数据给服务器,让它知道传感器状态'
133         data={
134                  "method": "response",
135                  "result":{
136                      "successful": True,
137                      "message": "xxxx",
138                      "data":[{
139                              "id": "POWER",
140                              "value": 0
141                          },
142                          {
143                              "id": "ledLight",
144                              "value": 0
145                          }
146                      ]
147                  }
148         }  # 固定格式
149         self.sendData(data)
150 
151     """=========================================  f = updateSensor  =============================================="""
152     def updateSensor(self):
153         '区分传感器标识'
154         data = str.lower(self.data["p1"])
155         if data:
156             if hasattr(self, data):
157                 func = getattr(self, data)
158                 func()
159 
160     def power(self):
161         '传感器power标识'
162         if self.data["p2"] == "1":
163             self.sendSuccess()
164             # conf.LED_STATUS = 1
165             print("open led")
166         elif self.data["p2"] == "0":
167             self.sendSuccess()
168             # conf.LED_STATUS = 0
169             print("close led")
170 
171     def ledlight(self):
172         '传感器ledlignt标识'
173         self.sendSuccess()
174         # conf.LED_VALUE = self.data["p2"]
175         print("led亮度为",self.data["p2"])
176 
177     def sendSuccess(self):
178         '返回接收数据成功'
179         data = {
180             "method": "response",
181             "result":
182                 {
183                     "successful": True,
184                     "message": "发送成功!"
185                 }
186         }
187         self.sendData(data)
188 
189     def sendData(self,data):
190         data = json.dumps(data)
191         data += head
192         self.sock.send(data.encode("gbk"))
193 
194 
195 
196 if __name__ == '__main__':
197     ch = ClientHandler()
198 # cd F:\tmp\python_date1\myDevice\bin
199 # python tcp_client.py connect
weChat.py

 

 

如果你不想在注册或者嫌麻烦也可以通过邮箱来发送命令

邮箱的代码在下面

  1 # -*- coding:utf8 -*-
  2 
  3 import smtplib
  4 from poplib import POP3_SSL
  5 from email.parser import Parser
  6 from email.header import Header
  7 from email.mime.text import MIMEText
  8 from email.mime.multipart import MIMEMultipart
  9 from email.utils import formataddr
 10 
 11 from core import dealFile
 12 import time
 13 import configparser
 14 import os, sys
 15 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 16 
 17 
 18 cf = configparser.ConfigParser()
 19 cf = dealFile.readConf(cf)
 20 
 21 smtpServer = cf.get("email", "smtpServer")  # 发送请求服务
 22 popServer = cf.get("email", "popServer")     # 接收请求服务
 23 
 24 # smtpSrcAddr = "270176392@qq.com"    # 发送的源邮箱
 25 # smtpSrcAddrPwd = "tromtljvidhgbibj"  # 发送源邮箱的请求码 密码
 26 smtpSrcAddr = cf.get("email", "smtpSrcAddr")
 27 smtpSrcAddrPwd = cf.get("email", "smtpSrcAddrPwd")
 28 
 29 smtpDstAddr = cf.get("email", "smtpDstAddr")    # 发送的目的邮箱
 30 smtpPort = cf.get("email", "smtpPort")
 31 
 32 
 33 
 34 def sendEmailTxt(msg):
 35     """发送文本内容"""
 36     massage = MIMEText(msg, "plain", "utf8")
 37     return massage
 38 
 39 
 40 def sendEmailFile(filename):
 41     """发送附件"""
 42     fileName = dealFile.getFilePath(filename)
 43     massage = MIMEText(open(fileName).read(), "base64", "utf8")
 44     massage['Content-Type'] = "application/octet-stream"
 45     massage['Content-Disposition'] = "attachment; filename = {name}".format(name=filename)
 46     return massage
 47 
 48 
 49 class SendEmail:
 50     """发送邮件类"""
 51     def __init__(self):
 52         """初始化"""
 53         self.massage = MIMEMultipart()
 54         self.massage['From'] = formataddr(["实验室", smtpSrcAddr])
 55         self.massage['To'] = formataddr(["to", smtpDstAddr])
 56         self.massage['Subject'] = Header("回复邮件", "utf8")
 57         self.server = smtplib.SMTP_SSL(smtpServer, smtpPort)
 58         pass
 59 
 60     def run(self, cmd):
 61         """解析命令"""
 62         if isinstance(cmd, str):
 63             if hasattr(self, cmd):
 64                 cmd = cmd.lower()
 65                 func = getattr(self, cmd)
 66                 func()
 67                 self.login(self.massage)
 68             self.quit()
 69         elif isinstance(cmd, list):
 70             for i in cmd:
 71                 if hasattr(self, i):
 72                     i = i.lower()
 73                     func = getattr(self, i)
 74                     func()
 75             if len(self.massage.get_payload())is 0:
 76                 return self.quit()
 77             self.login(self.massage)
 78             self.quit()
 79     pass
 80 
 81     def getlog(self):
 82         """得到日志"""
 83         sendStr = "{date} 最新日志\r\n".format(date=time.strftime("%Y-%m-%d"))
 84         massage = sendEmailTxt(sendStr)
 85         self.massage.attach(massage)
 86         massage = sendEmailFile("log.txt")
 87         print(massage)
 88         self.massage.attach(massage)
 89         pass
 90 
 91     def backlog(self):
 92         """备份日志"""
 93         backname = "log_{date}.txt".format(date=time.strftime("%Y.%m.%d.%X"))
 94         dealFile.backFile("log.txt", backname)
 95         sendStr = "备份成功\r\n"
 96         massage = sendEmailTxt(sendStr)
 97         self.massage.attach(massage)
 98         pass
 99 
100     def getlogall(self):
101         """得到所有日志"""
102         dealFile.joinFile()  # 拼接所有日志
103 
104         sendStr = "{date} 前的所有日志\r\n".format(date=time.strftime("%Y-%m-%d"))
105         massage = sendEmailTxt(sendStr)
106         self.massage.attach(massage)
107         massage = sendEmailFile("logback.txt")
108         print(massage)
109         self.massage.attach(massage)
110         pass
111 
112     def help(self):
113         """帮助文档"""
114         sendStr = "帮助文档!\r\n"
115         massage = sendEmailTxt(sendStr)
116         self.massage.attach(massage)
117         massage = sendEmailFile("help.txt")
118         print(massage)
119         self.massage.attach(massage)
120         pass
121 
122     def clean(self):
123         """清除所有日志"""
124         dealFile.cleanFile()   # 清除日志
125 
126         sendStr = "清除成功!\r\n"
127         massage = sendEmailTxt(sendStr)
128         self.massage.attach(massage)
129         pass
130 
131     def login(self, msg):
132         """登陆发送"""
133         self.server.login(smtpSrcAddr, smtpSrcAddrPwd)
134         self.server.sendmail(smtpSrcAddr, smtpDstAddr, msg.as_string())
135         pass
136 
137     def quit(self):
138         """退出"""
139         self.server.quit()
140         pass
141     pass
142 
143 
144 class GetEmail:
145     """获取邮件并解析"""
146     def __init__(self):
147         self.server = POP3_SSL(popServer)
148         pass
149 
150     def run(self):
151 
152         self.login()
153         cmd = self.getEmail()
154         self.deleEmail()
155         self.quit()
156         return cmd
157 
158     def getEmail(self):
159         """获取最新消息"""
160         num, size = self.server.stat()
161         if num > 0:
162             resp, list, octets = self.server.retr(num)
163             """分开list, 将信息变为emailMassger"""
164             msg = b"\r\n".join(list).decode("utf8")
165             msg = Parser().parsestr(msg)
166             """解析出命令"""
167             cmd = self.analyze(msg)
168             try:
169                 cmd = cmd.split(",")
170                 return cmd
171             except Exception as e:
172                 print(e)
173         return False
174         pass
175 
176     def deleEmail(self):
177         num, size = self.server.stat()
178         if num > 0:
179             for i in range(num):
180                 self.server.dele(i+1)
181         pass
182 
183     def analyze(self, msg):
184         """解析出msg中的文本内"""
185         if msg.is_multipart():
186             print("is_multipart")
187             parts = msg.get_payload()
188             part = parts[0]    # 得到第一个
189             content = part.get_payload(decode=True)
190             charset = self.gussCharset(part)  # 得到编码格式
191             if charset:
192                 content = content.decode(charset)
193                 return content
194         else:
195             print("is_not_multipart")
196             content_type = msg.get_content_type()
197             if content_type == 'text/plain' or content_type == 'text/html':
198                 content = msg.get_payload(decode=True)
199                 charset = self.gussCharset(msg)    # 得到编码格式
200                 if charset:
201                     content = content.decode(charset)
202                     return content
203             else:
204                 print("Attachment.........................")
205         pass
206 
207     def gussCharset(self, msg):
208         """获取编码格式"""
209         charset = msg.get_charset()
210         if charset is None:
211             content_type = msg.get("Content-Type", "").lower()
212             pos = content_type.find("charset=")
213             if pos > 0:
214                 charset = content_type[pos+8:]
215             return charset
216         pass
217 
218     def login(self):
219         self.server.user(smtpSrcAddr)
220         self.server.pass_(smtpSrcAddrPwd)
221         pass
222 
223     def quit(self):
224         self.server.quit()
225         pass
226 
227     pass
228 
229 
230 if __name__ == "__main__":
231     while True:
232         A = GetEmail()
233         cmd = A.run()
234         print(cmd)
235         time.sleep(10)
236         if cmd is not False:
237             B = SendEmail()
238             B.run(cmd)
239             time.sleep(10)
240     pass
emailSendReceive.py

 

6.最后看看主程序把

 分别写两个脚本运行就好了

 1 # -*- coding:utf8 -*-
 2 
 3 import os,sys
 4 import socketserver
 5 import threading
 6 import time
 7 from multiprocessing import Process
 8 
 9 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
10 sys.path.append(PATH)
11 
12 from core import Tcpserver
13 from core import clockIn
14 from core import oledshow
15 from core import emailSendReceive
16 from core import dealFile
17 import configparser
18 import core
19 
20 def TCP():
21     """tcp进程"""
22     # check = threading.Thread(target=Tcpserver.checkOccupy)
23     # check.start()
24     cf = configparser.ConfigParser()
25     cf = dealFile.readConf(cf)
26     ip = cf.get("TCP", "ip")
27     port = cf.getint("TCP", "port")
28     ip_port = (ip, port)
29     print("----等待连接.............")
30     s = socketserver.ThreadingTCPServer(ip_port, Tcpserver.SeverHandle)
31     s.serve_forever()
32     pass
33 
34 
35 def CLOCK(queueOled, queueToTcp, queueToClock, queueIsNewSql):
36     """检验进程"""
37     gpio = clockIn.ClockCheck(queueOled, queueToTcp, queueToClock, queueIsNewSql)
38     gpio.run()
39     pass
40 
41 
42 def OLED(queue):
43     """oled进程"""
44     oled = oledshow.Oled(queue)
45     oled.run()
46     pass
47 
48 
49 def EMAIL():
50     """邮件进程"""
51     while True:
52         A = emailSendReceive.GetEmail()
53         cmd = A.run()
54         print(cmd)
55         time.sleep(10)
56         if cmd is not False:
57             B = emailSendReceive.SendEmail()
58             B.run(cmd)
59             time.sleep(10)
60 
61 
62 def main():
63     # A = Process(target=TCP)
64     # B = Process(target=EMAIL)
65     C = threading.Thread(target=CLOCK, args=(core.qOledClock, core.qToTcpOccupy, core.qToClockOccupy, core.qIsNewSql))
66     D = threading.Thread(target=OLED, args=(core.qOledClock,))
67 
68     # A.start()
69     # B.start()
70     C.start()
71     D.start()
72     # A.join()
73     TCP()
74 
75 
76 if __name__ == "__main__":
77     main()
78     # TCP()
fingerStart.py
 1 # -*- coding:utf8 -*-
 2 
 3 from core import weChat
 4 
 5 def main():
 6     a = weChat.ClientHandler()
 7 
 8 
 9 if __name__ == "__main__":
10     main()
11     # TCP()
weChatClient.py

 逻辑结构图如下

 

 

 

 

 未经本人许可不得转载 谢谢!!!

posted @ 2019-06-23 09:22  开心的小草  阅读(4331)  评论(0编辑  收藏  举报