树莓派:基于物联网做的指纹打卡器
今天我就分享一波自己的成果。
心心念念的想做一个物联网的东西出来,终于在上个月搞定了,虽说肯定是有些漏洞(目前我是没有找出来的),但是效果看起来还不错。学了这么久的Python、Qt、liunx命令总算派上用场了。
材料:
- 树莓派一台
- 指纹模块(AS608光学指纹识别模块)
- OLED液晶屏
- usb转TTL
- 杜邦线
先说明一下
博客园无法分享附件就只能这样分享了
如果想要附件可以点击下面 链接,我在csdn上注册了一个号可以去下载:
先上个最终成果的图
看起来感觉还可以,基本完成了电脑和手机都可以获得日志的效果
大家最期待的过程了
现在我来说是我的想法和思路
刚开始看到隔壁实验室的指纹打卡机时好像是那种用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]
注意:
- 可以先在串口调试助手上输入命令,看看数据是怎么样子的然后在分析数据,最后写程序处理数据
- 按照说明书提示最好不要改 模块的地址和密码,不然可能会成为砖头
- 非常重要!!!本人是吃了亏的,真是日了狗, 指纹模块中有个设置波特率的,说明书上是说波特率可以设置为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()
下面是服务器可能用到的
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)
服务器完成后就可以写客户端端了。(其实是两个同时进行然后相互补充)
下面是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 }
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
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
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
当能够正常打卡后就需要在液晶屏上显示了
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()
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
如果你不想在注册或者嫌麻烦也可以通过邮箱来发送命令
邮箱的代码在下面
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
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()
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()
逻辑结构图如下
未经本人许可不得转载 谢谢!!!