zoukankan      html  css  js  c++  java
  • 树莓派:基于物联网做的指纹打卡器

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

      心心念念的想做一个物联网的东西出来,终于在上个月搞定了,虽说肯定是有些漏洞(目前我是没有找出来的),但是效果看起来还不错。学了这么久的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] + "
    "
     65             name = "name: " + i[1] + "
    "
     66             date = "date: " + i[2] + "
    "
     67             f.write(id + name + date + "
    ")
     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 + "
    ")
    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("
    ")
    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("
    ")
    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 + "
    
    "
    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:	mppython_date1myDevicein
    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} 最新日志
    ".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 = "备份成功
    "
     96         massage = sendEmailTxt(sendStr)
     97         self.massage.attach(massage)
     98         pass
     99 
    100     def getlogall(self):
    101         """得到所有日志"""
    102         dealFile.joinFile()  # 拼接所有日志
    103 
    104         sendStr = "{date} 前的所有日志
    ".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 = "帮助文档!
    "
    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 = "清除成功!
    "
    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"
    ".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

     逻辑结构图如下

     

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

  • 相关阅读:
    .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
    《ASP.NET Core 与 RESTful API 开发实战》-- (第10章)-- 读书笔记
    《ASP.NET Core 与 RESTful API 开发实战》-- (第9章)-- 读书笔记(下)
    《ASP.NET Core 与 RESTful API 开发实战》-- (第9章)-- 读书笔记(上)
    《ASP.NET Core 与 RESTful API 开发实战》-- (第8章)-- 读书笔记(尾)
    解决win10桌面图标变成白图标的问题
    微信小程序封装http请求
    Java如何控制某个方法允许并发访问的线程个数----Semaphore
    java实现获取用户IP地址
    shell有减号开头的参数的问题
  • 原文地址:https://www.cnblogs.com/kaixindexiaocao/p/11067673.html
Copyright © 2011-2022 走看看