今天我就分享一波自己的成果。
心心念念的想做一個物聯網的東西出來,終於在上個月搞定了,雖說肯定是有些漏洞(目前我是沒有找出來的),但是效果看起來還不錯。學了這么久的Python、Qt、liunx命令總算派上用場了。
材料:
- 樹莓派一台
- 指紋模塊(AS608光學指紋識別模塊)
- OLED液晶屏
- usb轉TTL
- 杜邦線
先說明一下
博客園無法分享附件就只能這樣分享了
如果想要附件可以點擊下面 鏈接,我在csdn上注冊了一個號可以去下載:
先上個最終成果的圖



看起來感覺還可以,基本完成了電腦和手機都可以獲得日志的效果
大家最期待的過程了
現在我來說是我的想法和思路
剛開始看到隔壁實驗室的指紋打卡機時好像是那種用usb讀取數據的(好像是節約成本吧),我就想能這也太不智能了吧,就想着能不能讓它智能些,比如通過電腦看到它的日志啊,或者用手機看到它的日志啊什么的(后來我才知道淘寶上TM已經出現這種完善的成品指紋考勤機了)。光想沒用啊,還是要靠實踐來檢驗真理。於是我就想到了手上的樹莓派,想想就有些興奮,可以向網上那些大佬一樣DIY一個東西出來了,由於我的知識有限,無法自己搞個指紋打卡模塊,就到網上買了一個,先開始買的正點原子的指紋模塊,原子哥不愧是我原子哥,和他討論問題時真是盡心盡力。文檔很好,不過他那個和模塊通信的程序不是很全,就幾個,可以能是直接儲存在模塊里的緣故,可是我不想儲存在模塊里啊,我學了Python加上Mysql,我想直接存在數據庫里,這樣更加安全可靠。於是我就開始解決通信問題,將他發回來的數據解碼,搗鼓了2天才完成,有點心酸。
先把配置文件分享了,下面代碼會用到
# 用戶root 給電腦連接的 [root] pwd = 123 # 數據庫 [db] db_port = 3306 db_user = root db_host = 127.0.0.1 db_pwd = 123456 db_database = finger db_table = test1 # smtpServer 發送請求服務 # popServer 接收請求服務 # smtpSrcAddr 服務端的地址 # smtpSrcAddrPwd 服務端的密碼 # smtpDstAddr 發送的目的郵箱 # smtpPort 端口號 qq端口號為 465 [email] smtpServer = smtp.qq.com popServer = pop.qq.com smtpSrcAddr = 發送請求的你的郵箱 smtpSrcAddrPwd = 允許的密碼 smtpDstAddr = 目的郵箱
smtpPort = 465 # TCP服務 [TCP] ip = 192.168.137.249 port = 9090 # 串口服務 [serial] port = /dev/ttyAMA0 (先不用這個串口,這個是我配置過的,你可以先用usb轉ttl連接樹莓派的usb口和指紋模塊) baudrate = 57600 timeout = 10 # 樂聯網 網關信息 [lewei] ip = tcp.lewei50.com port = 9960 userKey = 你自己的userKey gatewayNode = 02
1.首先要在電腦上調通指紋發送數據的所有命令
分享一波代碼
要用電腦和指紋模塊通信首先要裝
python要serial模塊,在cmd命令行中用命令 pip install serial 就可以下載serial 了
1 # -*-coding=utf8-*- 2 3 import serial 4 import serial.tools.list_ports 5 6 import os, sys 7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 sys.path.append(PATH) 9 10 SureCore = { 11 0x00: True, # 表示指令執行完畢或OK; 12 0x01: 101, # 表示數據包接收錯誤; 13 0x02: 102, # 表示傳感器上沒有手指; 14 0x03: 103, # 表示錄入指紋圖像失敗; 15 0x06: 202, # 表示指紋圖像太亂而生不成特征; 16 0x07: 203, # 表示指紋圖像正常,但特征點太少而生不成特征; 17 0x15: 204, # 表示圖像緩沖區內沒有有效原始圖而生不成圖像; 18 0x08: 302, # 表示指紋不匹配; 19 0x09: 402, # 表示沒搜索到;此時頁碼與得分為 0 20 0x0a: 502, # 表示合並失敗(兩枚指紋不屬於同一手指); 21 0x0d: 802, # 表示指令執行失敗; 22 0x0f: 1002, # 表示不能發送后續數據包; 23 } 24 '''返回= 999 校驗和錯誤''' 25 26 27 class DealBuff: 28 """切割收到的數據""" 29 HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF] 30 31 def __init__(self, buff): 32 self.buff = buff 33 """處理讀出的指紋數據用到""" 34 self.tag = list() # 包標識 35 self.data = list() 36 self.check = list() 37 pass 38 39 def read(self): 40 buff = [x for x in bytes(self.buff)] 41 check = self.slit(buff) 42 return self.tag, self.data, check 43 44 def listCut(self, buff, num): 45 """切割數組""" 46 rec = list() 47 for i in range(num): 48 bytes_buf = (buff.pop(0)) 49 # rec.append(buff.pop(0)) 50 rec.append(bytes_buf) 51 return rec, buff 52 pass 53 54 def slit(self, buff): 55 """"選擇數據""" 56 # 初始化中間變量 57 popList = list() 58 check_Num = 0 59 check = list() 60 head = list() 61 62 if len(buff) < 6: # 判斷是否有效數據 63 return True 64 65 head, buff = self.listCut(buff, 6) # 選擇出頭及判斷 66 for i in range(6): 67 if head[i] != self.HEAD[i]: 68 return False 69 70 popList, buff = self.listCut(buff, 1) # 取出包標識 71 self.tag.append(popList) 72 check_Num += popList[0] # 計算校驗和 73 74 popList, buff = self.listCut(buff, 2) # 取出包長度 75 check_Num += popList[0] + popList[1] # 計算校驗和 76 77 popList, buff = self.listCut(buff, popList[0] * 16 + popList[1]) # 取出包數據 78 check.append(popList.pop()) # 取出校驗數據 79 check.append(popList.pop()) 80 for i in popList: # 計算校驗和 81 check_Num += i 82 83 self.data.extend(popList) # 導入有用數據 84 if check_Num % 65535 != check[0] + check[1]*256: # 檢驗校驗和 85 return False 86 87 rec = self.slit(buff) # 得到是否正確分析完數據 88 return rec 89 pass 90 91 def write(self): 92 """要寫的數據打包""" 93 pack = self.dataSeparate(self.buff, 128) # 將數據分成每組128個元素 94 return pack 95 pass 96 97 def dataSeparate(self, buff, numPart): 98 """把數據分組打包""" 99 num = int(len(buff) / numPart) 100 newData = list() 101 for i in range(num): 102 newData.append(buff[i * numPart:(i+1) * numPart]) 103 104 packData = list() 105 for i in range(num-1): 106 data = self.packData(newData[i], 0x02) # 數據包沒結束 107 packData.extend(data) 108 109 packData.extend(self.packData(newData[num-1], 0x08)) # 數據包結束 110 return packData 111 pass 112 113 def packData(self, buff, flage): 114 num = len(buff) + 2 115 senddata = [flage, int(num / 256), int(num % 256)] + buff 116 sum = 0 117 for i in senddata: 118 sum += i 119 senddata = self.HEAD + senddata 120 senddata.append(int(sum / 256)) 121 senddata.append(int(sum % 256)) 122 return senddata 123 pass 124 125 pass 126 127 128 class DealFingeer: 129 """和指紋模塊交互""" 130 HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF] 131 tag = list() # 包標識 132 cmd = list() # 133 data = list() 134 ser = serial.Serial() 135 def __init__(self, cmd, data=None, server=None): 136 """初始化函數""" 137 self.cmd = cmd 138 self.data = data 139 self.server = server 140 pass 141 142 def run(self): 143 if hasattr(self, self.cmd): 144 func = getattr(self, self.cmd) 145 return func(self.data) 146 pass 147 148 def link(self): 149 """連接串口""" 150 self.ser.port = "COM5" 151 self.ser.baudrate = 57600 152 self.ser.bytesize = 8 153 self.ser.parity = 'N' 154 self.ser.xonxoff = 0 155 self.ser.rtscts = 0 156 self.ser.close() 157 self.ser.open() 158 pass 159 160 def finger(self, data): 161 self.link() 162 check = self.getImage() # 檢測獲取圖像 163 if check is not True: 164 return check, [] 165 166 self.link() 167 check = self.genChar(data) # 檢測生成特征值 168 if check is not True: 169 return check, [] 170 # ================= 生成特征值時圖像會清除,所以要重新采集 ========================== # 171 self.link() 172 check = self.getImage() # 檢測獲取圖像 173 if check is not True: 174 return check, [] 175 176 if self.server is not None: 177 self.server.send("True".encode("utf8")) # 發送數據說明准備好了 178 179 self.link() 180 check = self.upImage() # 上傳圖像 181 if check is not True: # 校驗和錯誤 182 return check, [] 183 self.tag, self.data = self.getUpImage() 184 185 if len(self.tag) is 0 and len(self.data) is 0: # 得到數據錯誤 186 return False, [] 187 return True, [] 188 189 def save(self, data=None): 190 self.link() 191 check = self.regModel() 192 if check is not True: # 校驗和錯誤 193 return check, [] 194 195 self.link() 196 check = self.upChar(data) # 上傳特征值 197 if check is not True: # 校驗和錯誤 198 return check, [] 199 self.tag, self.data = self.getUpChar() 200 201 if len(self.tag) is 0 and len(self.data) is 0: # 得到數據錯誤 202 return False, [] 203 return True, [] 204 pass 205 206 def check(self, data=None): 207 """檢驗指紋, 生成特征值""" 208 self.link() 209 check = self.match() # 比較指紋特征 210 if check is not True: 211 return check, [] 212 score = self.data[1]*255 + self.data[2] # 返回的分數值 213 214 self.link() 215 check = self.regModel() # 合成指紋特征值 216 if check is not True: 217 return check, [] 218 return True, score 219 pass 220 221 def isFinger(self, data=None): 222 """判斷現在的指紋和下載的指紋是否相同""" 223 self.link() 224 check = self.downCharCheck() 225 if check is not True: # 判斷是否可以發送數據 226 return check, [] 227 """下載指紋""" 228 self.link() 229 self.downCharData(data) 230 """檢驗指紋""" 231 self.link() 232 check = self.match() 233 if check is not True: 234 return check, [] 235 score = self.data[1] * 255 + self.data[2] # 返回的分數值 236 return True, score 237 pass 238 239 def getImage(self, data=None): 240 """獲取圖像""" 241 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05] # 發送命令獲取內容 242 return self.isOk(cmd, 12) 243 pass 244 245 def genChar(self, data=None): 246 """生成特征文件""" 247 if data == "1": 248 cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x01, 0x00, 0x08] # 發送命令 249 return self.isOk(cmd, 12) # 圖像接收數據 12 大小 250 elif data == "2": 251 cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x02, 0x00, 0x09] # 發送命令 252 return self.isOk(cmd, 12) # 圖像接收數據 12 大小 253 pass 254 255 def match(self, data=None): 256 """比較指紋特征""" 257 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x03, 0x00, 0x07] # 發送命令獲取內容 258 return self.isOk(cmd, 14) 259 pass 260 261 def regModel(self, data=None): 262 """合成指紋特征值""" 263 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09] # 發送命令獲取內容 264 return self.isOk(cmd, 12) 265 pass 266 267 def upChar(self, data=None): 268 """上傳特征模塊檢測""" 269 buff = bytes() 270 if data == "1": 271 cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x01, 0x00, 0x0e] # 發送命令 272 return self.isOk(cmd, 12, False) 273 elif data == "2": 274 cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0F] # 發送命令 275 return self.isOk(cmd, 12, False) 276 pass 277 278 def getUpChar(self, data=None): 279 """上傳特征模塊數據""" 280 buff = self.ser.read(834) 281 self.ser.close() 282 subpackage = DealBuff(buff) # 分割內容 283 self.tag, self.data, check = subpackage.read() 284 if check is not True: # 校驗和錯誤 285 return 999 286 return self.tag, self.data 287 288 def downCharCheck(self, data=None): 289 """ 290 下載特征值檢測 291 先要初始化,發送獲取圖像命令 292 """ 293 self.getImage() 294 self.link() 295 cmd = self.HEAD + [0x01, 0x00, 0x04, 0x09, 0x02, 0x00, 0x10] # 發送命令 下載的數據放在buff2中 296 return self.isOk(cmd, 12) 297 pass 298 299 def downCharData(self, data): 300 """下載特征值的數據""" 301 self.writeRead(data, 0) # 發送數據 接收為0 302 pass 303 304 305 def upImage(self, data=None): 306 """上傳圖像檢測""" 307 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x0a, 0x00, 0x0e] # 發送命令 308 return self.isOk(cmd, 12, False) 309 pass 310 311 def getUpImage(self, data=None): 312 """獲取后續的圖像數據""" 313 buff = self.ser.read(40032) 314 self.ser.close() 315 subpackage = DealBuff(buff) # 分割內容 316 self.tag, self.data, check = subpackage.read() 317 if check is not True: # 校驗和錯誤 318 return [], [] 319 return self.tag, self.data 320 321 def writeRead(self, cmd, length, close=True): 322 """發送命令讀取原始字節""" 323 cmd = bytes(cmd) 324 self.ser.write(cmd) 325 buff = self.ser.read(length) # 圖像接收數據 326 if close: 327 self.ser.close() # 接受完數據斷開com 328 return buff 329 pass 330 331 def isOk(self, cmd, length, close=True): 332 """判斷數據是否合格""" 333 buff = self.writeRead(cmd, length, close) # 圖像接收數據 12 大小 334 subpackage = DealBuff(buff) # 分割內容 335 self.tag, self.data, check = subpackage.read() 336 # 檢驗數據是否可靠 337 if check is not True: # 校驗和錯誤 338 return 999 339 return self.check_code(self.data) 340 pass 341 342 def check_code(self, data): 343 """檢驗指令碼""" 344 return SureCore[data[0]] 345 pass 346 347 pass 348 349 350 if __name__ == "__main__": 351 # HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF] 352 # data = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x0A, 0x00, 0x0E] 353 # data = HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05] 354 # data = HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09] 355 # data = HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0f]
注意:
- 可以先在串口調試助手上輸入命令,看看數據是怎么樣子的然后在分析數據,最后寫程序處理數據
- 按照說明書提示最好不要改 模塊的地址和密碼,不然可能會成為磚頭
- 非常重要!!!本人是吃了虧的,真是日了狗, 指紋模塊中有個設置波特率的,說明書上是說波特率可以設置為9600倍數,其實並不是這樣的,我先開始覺得速度太慢了就設置了先開始是12倍,覺得可以用還是太慢,就設置了24倍,還是可以用,但是還是慢,我一沖動就設置成了96倍,我的個乖乖,然后就是不管怎么喚它都沒反應,為此我還和原子哥討論了很久,結果就是這東西成板磚了。 然后不得已就又買了個便宜的(原子哥雖然服務好,技術支持好,就是東西太貴了,弄懂原理了就不用再買貴的了)。
2.就是寫一個服務器和客戶端啦
我是用Qt寫的客戶端,用python寫的服務器,模擬兩個電腦通信(雖然只要一個自己的電腦)
先來一波服務器的代碼
里面用到了mySql, 用來存儲指紋數據
同時為了上傳圖像到客戶端還要下載numpy, PIL 模塊,其中python3中沒有PIL 要下pillow
用到的cmd命令 pip install numpy, pip install pillow
1 # -*-coding=utf8-*- 2 3 import socketserver 4 from collections import Iterable 5 import json 6 7 import os, sys 8 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 9 sys.path.append(PATH) 10 11 from core import dealFinger 12 from core.dealFinger import DealFinger 13 from core.dealSql import mySqlDeal 14 from core import dealFile 15 from core import clockIn 16 import core 17 18 import configparser 19 20 check = { 21 0x00: True, # 表示指令執行完畢或OK; 22 0x01: 101, # 表示數據包接收錯誤; 23 0x02: 102, # 表示傳感器上沒有手指; 24 0x03: 103, # 表示錄入指紋圖像失敗; 25 0x06: 202, # 表示指紋圖像太亂而生不成特征; 26 0x07: 203, # 表示指紋圖像正常,但特征點太少而生不成特征; 27 0x15: 204, # 表示圖像緩沖區內沒有有效原始圖而生不成圖像; 28 0x08: 302, # 表示指紋不匹配; 29 0x09: 402, # 表示沒搜索到;此時頁碼與得分為 0 30 0x0a: 502, # 表示合並失敗(兩枚指紋不屬於同一手指); 31 0x0d: 802, # 表示指令執行失敗; 32 0x0f: 1002, # 表示不能發送后續數據包; 33 "occupyError": "occupyError", # 占用指紋資源失敗 34 "releaseError": "releaseError", # 釋放指紋資源失敗 35 "getLogError": "getLogError", # 獲取日志失敗 36 "findError": "findError", # 查找人失敗 37 "outPutError": "outPutError" # 導出數據庫失敗 38 } 39 40 isTcpOccupy = 0 41 42 class JudgeLoad: 43 """判斷是否是合理的用戶登陸""" 44 def __init__(self, server, addrIP): 45 self.server = server 46 self.addrIP = addrIP 47 pass 48 49 def isLoad(self, data, addr): 50 """判斷是否登陸成功""" 51 if isinstance(data, dict): 52 isTrue1 = self.isFind("userName", data.keys()) # 判斷類型是否符合 53 isTrue2 = self.isFind("passWord", data.keys()) # 判斷類型是否符合 54 if isTrue1 is True and isTrue2 is True: 55 return self.isUser(data["userName"], data["passWord"], addr) 56 else: 57 isTrue = self.isFind(self.addrIP, addr) # 判斷是否有登陸過 58 if isTrue is not True: 59 return False 60 isTrue1 = self.isFind("cmd", data.keys()) # 判斷類型是否符合 61 isTrue2 = self.isFind("value", data.keys()) # 判斷類型是否符合 62 if isTrue1 is True and isTrue2 is True: 63 return True 64 return False 65 return False 66 pass 67 68 def isUser(self, user, pwd, addr): 69 """判斷用戶名和密碼是否正確""" 70 try: 71 cf = configparser.ConfigParser 72 cf = dealFile.readConf(cf) 73 pwdconf = cf.get(user, "pwd") 74 if pwd == pwdconf: 75 ischeck = self.isFind(self.addrIP, addr) 76 if ischeck is not True: 77 addr.append(self.addrIP) # 添加主機ip 確定登陸成功 78 self.server.send("True".encode("utf8")) 79 return "loadSuccess" 80 except Exception as e: 81 print(e) 82 return "loadFalse" 83 pass 84 85 def isFind(self, child, parent): 86 """尋找parent 中是否有 child""" 87 if isinstance(parent, Iterable) is not True: # 判斷是否是可迭代類型 88 return False 89 for i in parent: 90 if child == i: 91 return True 92 return False 93 pass 94 95 pass 96 97 98 class SeverHandle(socketserver.BaseRequestHandler): 99 """ 100 任務分發 101 將客戶端的請求分發下去 102 """ 103 # addr = ["127.0.0.1"] 104 addr = list() 105 Occupy = list() 106 def init(self): 107 self.Finger = None 108 pass 109 110 def handle(self): 111 """連接的一個客戶端""" 112 self.init() 113 print("------------------連接成功-----------------") 114 print("conn :", self.request) 115 print("addr :", self.client_address) 116 # 接收客戶端數據 117 buff = self.request.recv(1024).decode("utf8") 118 data = eval(buff) 119 120 judgeLode = JudgeLoad(self.request, self.client_address[0]) 121 isTrue = judgeLode.isLoad(data, self.addr) # 判斷是否登陸 122 if isTrue is not True: 123 if isTrue is "loadSuccess": 124 return 125 elif isTrue is "loadFalse": 126 print("error") 127 self.request.send("error".encode("utf8")) 128 return 129 elif isinstance(data, dict): 130 isTrue1 = judgeLode.isFind("cmd", data.keys()) # 判斷類型是否符合 131 isTrue2 = judgeLode.isFind("value", data.keys()) # 判斷類型是否符合 132 if isTrue1 is True and isTrue2 is True: 133 print("error") 134 self.request.send("error".encode("utf8")) 135 return 136 137 print(data) 138 if hasattr(self, data["cmd"]): # 命令分發 139 func = getattr(self, data["cmd"]) 140 func(data["cmd"], data["value"]) 141 pass 142 143 def finger(self, cmd, value): 144 """采集手指數據""" 145 self.Finger = DealFinger(cmd, value, self.request) 146 check, buff = self.Finger.run() 147 if check is not True: 148 self.request.send(str(check).encode("utf8")) 149 return 150 print(self.Finger.data) 151 fileName = dealFile.createImage(self.Finger.data, "finger.bmp") 152 self.sendData(fileName) 153 154 def check(self, cmd, value): 155 """檢驗指紋是否合格""" 156 self.Finger = DealFinger(cmd, value, self.request) 157 check, score = self.Finger.run() 158 159 if check is not True: 160 self.request.send(str(check).encode("utf8")) 161 return 162 senddata = "%s##%s" % ("True", score) # 拼接發送格式 163 self.request.send(senddata.encode("utf8")) 164 pass 165 166 def save(self, cmd, data): 167 """儲存數據到數據庫""" 168 self.Finger = DealFinger(cmd, "2") # 讀取buff2 中的模板 169 check, buff = self.Finger.run() 170 171 if check is not True: 172 self.request.send(str(check).encode("utf8")) 173 return 174 """儲存到硬件""" 175 dataFinger = list() 176 dataFinger.append(self.Finger.data) 177 self.Finger = DealFinger("saveToHard") # 讀取buff2 中的模板 178 check, buff = self.Finger.run() 179 if check is not True: 180 self.request.send(str(check).encode("utf8")) 181 return 182 print(buff) 183 num = buff[1] * 256 + buff[2] 184 print(num) 185 """儲存到數據庫里""" 186 print(data) 187 buff = data.split("##") 188 data = { 189 "num": num, 190 "id": buff[0], 191 "name": buff[1], 192 "date": buff[2], 193 "finger": str(dataFinger[0]) 194 } 195 sql = mySqlDeal("insertData", data) # 儲存指紋 196 sql.run() 197 print("save True......") 198 self.request.send("True".encode("utf8")) # 發送成功信息 199 """發送更新檢測指紋""" 200 core.qIsNewSql.put(True) 201 pass 202 203 def occupy(self, cmd, data): 204 global isTcpOccupy 205 """搶占指紋""" 206 if isTcpOccupy is 1: 207 senddata = "%s" % (check["occupyError"]) # 拼接發送格式 208 self.request.send(senddata.encode("utf8")) 209 return 210 211 core.qToClockOccupy.put(True) 212 213 if isTcpOccupy is 2: 214 pop = self.Occupy.pop() 215 print(pop) 216 if pop != self.client_address[0]: 217 senddata = "%s" % (check["occupyError"]) # 拼接發送格式 218 self.request.send(senddata.encode("utf8")) 219 return 220 self.Occupy.append(self.client_address[0]) # 記錄哪個客戶端 221 222 isTcpOccupy = 2 # 標記客戶端搶占的 223 self.request.send("True".encode("utf8")) # 發送成功信息 224 225 def release(self, cmd, data): 226 """釋放指紋""" 227 global isTcpOccupy 228 229 core.qToClockOccupy.put(False) 230 231 if isTcpOccupy is 0: 232 senddata = "%s" % (check["releaseError"]) # 拼接發送格式 233 self.request.send(senddata.encode("utf8")) 234 return 235 isTcpOccupy = 0 236 self.Occupy.pop() 237 self.request.send("True".encode("utf8")) # 發送成功信息 238 239 def getLog(self, cmd, data): 240 """獲取日志""" 241 fileName = dealFile.getFilePath("log.txt") 242 if fileName is False: 243 self.request.send(check["getLogError"].encode("utf8")) # 發送成功信息 244 return 245 self.request.send("True".encode("utf8")) # 發送成功信息 246 self.sendData(fileName) 247 pass 248 249 def findPeople(self, cmd, data): 250 """查找人""" 251 sql = mySqlDeal("selectId", data) # 查找 252 ch, data = sql.run() 253 if ch is False: 254 self.request.send(check["findError"].encode("utf8")) # 發送成功信息 255 return 256 self.request.send("True".encode("utf8")) # 發送成功信息 257 fileName = dealFile.createFindFile(data, "find.txt") 258 self.sendData(fileName) 259 pass 260 261 def delectPeople(self, cmd, data): 262 """刪除數據""" 263 sql = mySqlDeal("selectNum", data) # 刪除 264 check, fingerNum = sql.run() 265 for i in fingerNum: 266 num = int(i[0]) 267 self.Finger = DealFinger("psDeletChar", num) 268 self.Finger.run() 269 sql = mySqlDeal("delectId", data) # 刪除 270 sql.run() 271 self.request.send("True".encode("utf8")) # 發送成功信息 272 pass 273 274 def databaseBack(self, cmd, data): 275 ch, fileName = dealFile.outPutSql("fingerSql.sql") 276 if ch is False: 277 self.request.send(check["outPutError"].encode("utf8")) # 發送成功信息 278 return 279 self.request.send("True".encode("utf8")) # 發送成功信息 280 self.sendData(fileName) 281 pass 282 283 def updateDatabase(self, cmd, data): 284 buff = data.split("##") 285 fileName = buff[0] 286 fileSize = int(buff[1]) 287 self.request.send("True".encode("utf8")) # 發送成功信息 288 self.getFile(fileName, fileSize) 289 check = dealFile.creatSql(fileName) 290 if check is not True: 291 return None 292 mysql = mySqlDeal("selectAll") 293 check, data = mysql.run() 294 if check is not True: 295 return None 296 """儲存指紋""" 297 self.Finger = DealFinger("creatFinger", data) 298 self.Finger.run() 299 300 pass 301 302 def close(self, cmd, data): 303 """客戶端退出""" 304 for i in self.addr: 305 if i is self.client_address[0]: 306 self.addr.remove(i) 307 pass 308 309 def sendData(self, path): 310 """發送文件""" 311 fizeSize = os.path.getsize(path) 312 fileName = os.path.basename(path) 313 senddata = "{fileName}##{fileSize}" .format(fileName=fileName, fileSize=fizeSize) # 拼接發送格式 314 self.request.send(senddata.encode("utf8")) 315 check = self.request.recv(1024).decode("utf8") 316 print("send......") 317 print(check) 318 if check != "True": # 確定用戶接收到了數據 319 self.request.send("error".encode("utf8")) 320 return 321 print("send......again") 322 with open(path, "rb") as f: # 開始發送文件 323 num = 0 324 while num < fizeSize: 325 data = f.read(1024) 326 self.request.sendall(data) 327 num += len(data) 328 print("send ok") 329 pass 330 331 def getFile(self, path, size): 332 fileName = dealFile.getFilePath(path) 333 fileSize = size 334 with open(fileName, "w") as f: # 得到上傳的文件 335 num = 0 336 while num < fileSize: 337 data = self.request.recv(1024) 338 num = num + len(data) 339 data = data.decode("utf8") 340 f.write(data) 341 print("get OK") 342 pass 343 344 345 def checkOccupy(): 346 global isTcpOccupy 347 while True: 348 if isTcpOccupy == 0: 349 if core.qToTcpOccupy.empty() is not True: 350 isTcpOccupy = core.qToTcpOccupy.get() 351 pass 352 353 354 if __name__ == "__main__": 355 356 ip_port = ("192.168.137.249", 9090) 357 print("----等待連接.............") 358 s = socketserver.ThreadingTCPServer(ip_port, SeverHandle) 359 360 s.serve_forever()
下面是服務器可能用到的
1 # -*- coding:utf8 -*- 2 3 import numpy as np 4 from PIL import Image 5 6 import os, sys 7 import configparser 8 9 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 10 sys.path.append(PATH) 11 12 """存放文件的目錄""" 13 path = PATH + "/static/" 14 15 """ 16 對文件的一下操作 17 """ 18 19 20 def readConf(cf): 21 """讀取conf文件""" 22 fileName = PATH + "/conf/" + "conf.conf" 23 cf = configparser.ConfigParser() 24 cf.read(fileName) 25 return cf 26 27 28 def createImage(data, fileName): 29 """創建圖像""" 30 if isinstance(data, list) is not True: 31 return False 32 """得到指紋圖像的灰度bmp圖""" 33 ByteArray = bytearray(data) # 將數組轉換成 字節數組 34 NumpyArray = np.array(ByteArray) 35 grayImage = NumpyArray.reshape(288, 128) # 得到灰度圖像字節數組 36 image = Image.fromarray(grayImage) 37 fileName = path + fileName # 文件存放路徑 38 image.save(fileName) # 得到指紋圖像 39 return fileName 40 pass 41 42 43 def textLog(data, fileName): 44 """寫日志""" 45 fileName = path + fileName # 文件存放路徑 46 with open(fileName, "a+") as f: 47 f.write(data) 48 return 49 pass 50 51 def getFilePath(fileName): 52 """回取文件路徑""" 53 fileName = path + fileName 54 if os.path.isfile(fileName) is False: 55 return False 56 return fileName 57 pass 58 59 def createFindFile(data, fileName): 60 """生成查找文件""" 61 fileName = path + fileName 62 with open(fileName, "w+") as f: 63 for i in data: 64 id = "id : " + i[0] + "\r\n" 65 name = "name: " + i[1] + "\r\n" 66 date = "date: " + i[2] + "\r\n" 67 f.write(id + name + date + "\r\n") 68 return fileName 69 70 71 cf = configparser.ConfigParser() 72 cf = readConf(cf) 73 host = cf.get("db", "db_host") 74 port = cf.getint("db", "db_port") 75 user = cf.get("db", "db_user") 76 passwd = cf.get("db", "db_pwd") 77 db = cf.get("db", "db_database") 78 table = cf.get("db", "db_table") 79 80 """導出數據庫""" 81 def outPutSql(fileName, host=host, port=port, user=user, passwd=passwd, db=db, table=table): 82 """導出mysql腳本""" 83 fileName = path + fileName 84 sqlStr = "mysqldump -u{user} -p{passwd} {db}> {fileName}"\ 85 .format(user=user, passwd=passwd, db=db, table=table, fileName=fileName) 86 try: 87 os.system(sqlStr) 88 except Exception as e: # 找不到數據庫 89 return False, None 90 # print(os.path.getsize(fileName)) 91 return True, fileName 92 pass 93 94 95 """創建數據庫""" 96 def creatSql(fileName, host=host, port=port, user=user, passwd=passwd, db=db, table=table): 97 """創建數據庫表""" 98 fileName = path + fileName 99 sqlStrDelect = "mysqladmin -u{user} -p{passwd} drop {db} -f"\ 100 .format(user=user, passwd=passwd, db=db) 101 sqlStrCreat = "mysqladmin -u{user} -p{passwd} create {db}" \ 102 .format(user=user, passwd=passwd, db=db, fileName=fileName) 103 sqlStrInsert = "mysql -u{user} -p{passwd} {db} < {fileName}" \ 104 .format(user=user, passwd=passwd, db=db, fileName=fileName) 105 try: 106 """刪除數據庫""" 107 a = os.system(sqlStrDelect) 108 print(a) 109 """創建數據庫""" 110 a = os.system(sqlStrCreat) 111 print(a) 112 """插入數據庫""" 113 a = os.system(sqlStrInsert) 114 print(a) 115 except Exception as e: # 找不到數據庫 116 print(e) 117 return False, None 118 return True 119 120 121 def backFile(fileName, backName): 122 """備份文件""" 123 fileName = path + fileName 124 backName = path + backName 125 logcontent = path + "logContent.txt" 126 with open(fileName, "rb") as f1, open(backName, "wb") as f2: 127 data = f1.read() 128 f2.write(data) 129 with open(fileName, "w") as f1: 130 pass 131 """添加log目錄""" 132 with open(logcontent, "a+") as f1: 133 f1.write(backName + "\r\n") 134 return True 135 pass 136 137 138 def joinFile(): 139 """拼接日志""" 140 log = path + "log.txt" 141 logcontent = path + "logContent.txt" 142 logback = path + "logback.txt" 143 with open(logback, "w") as f2: 144 pass 145 with open(logcontent) as f1, open(logback, "a+") as f2: 146 data = f1.read().strip() 147 num = len(data) 148 if num == 0: # 判斷文科是否為空 149 with open(log) as f3: 150 filestream = f3.read() 151 f2.write(filestream) 152 return 153 data = data.split("\n") 154 print(data) 155 for i in data: 156 with open(i) as f3: 157 filestream = f3.read() 158 f2.write(filestream) 159 with open(log) as f3: 160 filestream = f3.read() 161 f2.write(filestream) 162 pass 163 164 165 def cleanFile(): 166 """清空無用的日志文件""" 167 filename = path + "log_*" 168 logcontent = path + "logContent.txt" 169 with open(logcontent, "w"): # 文件目錄清空 170 pass 171 cmd = "rm {filename}".format(filename=filename) 172 data = os.system(cmd) 173 pass 174 175 if __name__ == "__main__": 176 # print(PATH) 177 # print(type(PATH)) 178 # print(path) 179 # print(type(path)) 180 # print(createImage(123, 456)) 181 # fileName = outPutSql("my.sql") 182 # print(fileName) 183 # print(os.path.getsize(fileName[1])) 184 185 # backFile("simsun.ttc", "backsimsun.ttc") 186 joinFile() 187 # creatSql("123") 188 # cleanFile() 189 # logconvim tent = path + "logContent.txt" 190 # with open(logcontent) as f1: 191 # data = f1.read().strip() 192 # print(data) 193 # num = len(data) 194 # 195 # data = data.split("\n") 196 # print(data)
服務器完成后就可以寫客戶端端了。(其實是兩個同時進行然后相互補充)
下面是Qt代碼
主要是通訊,其他的界面其實都還好,就按照自己的想法
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 #include "QDebug" 4 #include "QPainter" 5 #include "QBrush" 6 #include "QPaintDevice" 7 #include "QMessageBox" 8 #include "QSqlDatabase" 9 #include "QSqlError" 10 #include "QString" 11 #include "QFileDialog" 12 13 MainWindow::MainWindow(QWidget *parent) : 14 QMainWindow(parent), 15 ui(new Ui::MainWindow) 16 { 17 ui->setupUi(this); 18 initData();//初始化數據函數 19 initTcp(); 20 } 21 22 MainWindow::~MainWindow() 23 { 24 delete ui; 25 } 26 27 28 //初始化數據函數 29 void MainWindow::initData() 30 { 31 /* ================== 初始化登陸 ==================*/ 32 showImage = 3; 33 //設置當前顯示頁面 34 ui->stackedWidget->setCurrentWidget(ui->pageLog); 35 //沒登陸不使能菜單,設置密碼不可見 36 ui->menuO->setEnabled(false); 37 //設置編輯框模式 38 ui->lineEditUserName->setEnabled(true); 39 ui->lineEditPassward->setEnabled(true); 40 ui->lineEditPassward->setEchoMode(QLineEdit::Password); 41 ui->pB_logoChangelink->setStyleSheet("#pB_logoChangelink{border: 0px;}" 42 "#pB_logoChangelink:hover{color:rgb(0, 170, 255)};"); 43 isChangeLink=false; 44 /* ================== 初始化界面1 ==================*/ 45 //顯示文本框 46 ui->textEdit_1_Show->setEnabled(true); 47 ui->pushButton_1_get->setEnabled(true); 48 ui->pushButton_1_show->setEnabled(true); 49 ui->progressBar_1_get->setValue(0); 50 ui->progressBar_1_get->hide(); 51 /* ================== 初始化界面2 ==================*/ 52 //button 53 isOccupy = false; 54 ui->pushButton_2_Start->setText("開啟"); 55 ui->pushButton_2_Start->setEnabled(true); 56 ui->pushButtonConcel->setEnabled(false); 57 ui->pushButtonSure->setEnabled(false); 58 ui->pushButtoncheckfinger->setEnabled(false); 59 ui->pushButtonSavefinger1->setEnabled(false); 60 ui->pushButtonSavefinger2->setEnabled(false); 61 //label 62 ui->label_2_info->setText("請放入手指!"); 63 ui->label_2_info->hide(); 64 //progressBar 65 ui->progressBar_2_fingerImage->hide(); 66 67 /* ================ 初始化界面3 ====================== */ 68 findWhat = "id"; 69 ui->pushButton_3_findName->setText("查找id:"); 70 ui->pushButton_3_find->setEnabled(true); 71 ui->lineEdit_3_findId->setEnabled(true); 72 ui->pushButton_3_delect->setEnabled(false); 73 ui->pushButton_3_back->setEnabled(true); // 備份 74 ui->pushButton_3_Updata->setEnabled(true); // 上傳 75 ui->progressBar_3_show->setValue(0); 76 ui->progressBar_3_show->hide(); 77 ui->pushButton_3_findName->setStyleSheet("#pushButton_3_findName{border: 0px;}" 78 "#pushButton_3_findName:hover{color:rgb(0, 170, 255)};"); 79 80 81 /*===================== tcp數據 ======================*/ 82 //文件接收 83 isStart = true; 84 //初始化tcp登陸 85 isLoad = false; 86 callFunc = 0; 87 recWhat = 0; 88 showInfo = false; 89 } 90 91 //初始化有關tcp connect 92 void MainWindow::initTcp() 93 { 94 //ip和端口 95 // ip = "127.0.0.1"; 96 // port = 8080; 97 98 ip = "192.168.137.249"; 99 port = 9090; 100 //套接字 101 tcpSocket = new QTcpSocket(this); 102 //接收到服務器后發數據 103 connect(tcpSocket, &QTcpSocket::connected, this, &MainWindow::sendDataToServe); 104 //收信號 105 connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::dealReceiveData); 106 //對話框 × 掉 107 // connect(this, &MainWindow::destroyed, this, &MainWindow::on_actionClose_triggered); 108 connect(this, &MainWindow::destroyed, this, 109 [=]() 110 { 111 qDebug() << "distory"; 112 } 113 ); 114 } 115 116 //設置tcp連接 117 bool MainWindow::tcpLink(int mode) 118 { 119 //tcp連接等待超時 120 tcpSocket->disconnectFromHost(); 121 tcpSocket->close(); 122 tcpSocket->connectToHost(QHostAddress(ip), port); 123 124 if(!tcpSocket->waitForConnected(100)) //等待5s 125 { 126 if(0 == mode) 127 { 128 recCheck("link_error"); 129 } 130 return false; 131 } 132 return true; 133 } 134 135 //成功連接服務器后的響應 136 void MainWindow::sendDataToServe() 137 { 138 switch (callFunc) { 139 case 1: {//登陸請求 140 //給對方發送數據,使用套接字是tcpSocket; QString->QByteArray->char* 141 QString userName = ui->lineEditUserName->text(); 142 QString passWord = ui->lineEditPassward->text(); 143 QString sendData = QString("{'userName':'%1', 'passWord':'%2'}") 144 .arg(userName).arg(passWord); 145 tcpSocket->write(sendData.toUtf8().data()); 146 } 147 break; 148 case 2: {//發送錄制指紋1 149 QString cmd = "finger"; 150 QString data = "1"; 151 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 152 tcpSocket->write(sendData.toUtf8().data()); 153 } 154 break; 155 case 3: {//發送錄制指紋2 156 QString cmd = "finger"; 157 QString data = "2"; 158 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 159 tcpSocket->write(sendData.toUtf8().data()); 160 } 161 break; 162 case 4: {//發送校驗信息 163 QString cmd = "check"; 164 QString data = "None"; 165 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 166 tcpSocket->write(sendData.toUtf8().data()); 167 } 168 break; 169 case 5: {//存儲有效指紋數據 170 QString cmd = "save"; 171 QString name = ui->lineEditname->text(); 172 QString id = ui->lineEditID->text(); 173 QString date = ui->lineEditdate->text(); 174 QString data = QString("%1##%2##%3").arg(id).arg(name).arg(date); 175 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 176 tcpSocket->write(sendData.toUtf8().data()); 177 } 178 break; 179 case 6:{ // 發送占用指紋資源 180 QString cmd = "occupy"; 181 QString data = "None"; 182 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 183 tcpSocket->write(sendData.toUtf8().data()); 184 } 185 break; 186 case 7:{ // 發送釋放指紋資源 187 QString cmd = "release"; 188 QString data = "None"; 189 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 190 tcpSocket->write(sendData.toUtf8().data()); 191 } 192 break; 193 case 8:{ // 界面1獲取log 194 QString cmd = "getLog"; 195 QString data = "None"; 196 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 197 tcpSocket->write(sendData.toUtf8().data()); 198 } 199 break; 200 case 9:{ // 查找人 201 QString cmd = "findPeople"; 202 QString data = QString("%1:%2").arg(findWhat).arg(ui->lineEdit_3_findId->text()); 203 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 204 tcpSocket->write(sendData.toUtf8().data()); 205 } 206 break; 207 case 10:{ // 刪除信息 208 QString cmd = "delectPeople"; 209 QString data = QString("%1:%2").arg(findWhat).arg(ui->lineEdit_3_findId->text()); 210 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 211 tcpSocket->write(sendData.toUtf8().data()); 212 } 213 break; 214 case 11:{ // 備份數據庫 215 QString cmd = "databaseBack"; 216 QString data = "None"; 217 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 218 tcpSocket->write(sendData.toUtf8().data()); 219 } 220 break; 221 case 12:{ // 上傳數據庫 222 QString cmd = "updateDatabase"; 223 QString data = QString("%1##%2").arg(upDateFileName).arg(upDateFileSize); 224 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 225 tcpSocket->write(sendData.toUtf8().data()); 226 } 227 break; 228 case 20: {//發送退出程序信號 229 QString cmd = "close"; 230 QString data = "None"; 231 QString sendData = QString("{'cmd':'%1', 'value':'%2'}").arg(cmd).arg(data); 232 tcpSocket->write(sendData.toUtf8().data()); 233 tcpSocket->disconnectFromHost(); //關閉tcp 234 tcpSocket->close(); 235 QMainWindow::close(); 236 } 237 break; 238 default: 239 break; 240 } 241 } 242 243 //接收事件槽函數 244 void MainWindow::dealReceiveData() 245 { 246 //接收的數據 247 switch (callFunc) { 248 case 1: {// 登陸獲取信息 249 QByteArray buf = tcpSocket->readAll(); 250 QString check = QString(buf); 251 tcpSocket->disconnectFromHost(); //關閉tcp 252 tcpSocket->close(); 253 if(check != "True") // 登陸失敗或連接錯誤 254 { 255 recCheck(check); 256 return ; 257 } 258 //登陸成功 259 showImage = 1; 260 isLoad = true; 261 ui->menuO->setEnabled(true); 262 ui->stackedWidget->setCurrentWidget(ui->pageShowInfo); 263 264 } break; 265 266 case 2:{ //接收錄制指紋1 267 QByteArray buf = tcpSocket->readAll(); 268 QString check = QString(buf); 269 if(check != "True") 270 { 271 recCheck(check); 272 tcpSocket->disconnectFromHost(); //關閉tcp 273 tcpSocket->close(); 274 break ; 275 } 276 ui->label_2_info->setText("請等待---"); 277 ui->label_2_info->show(); 278 ui->progressBar_2_fingerImage->show(); 279 callFunc = 20; 280 } break; 281 282 case 3:{ //接收錄制指紋2 283 QByteArray buf = tcpSocket->readAll(); 284 QString check = QString(buf); 285 if(check != "True") 286 { 287 recCheck(check); 288 tcpSocket->disconnectFromHost(); //關閉tcp 289 tcpSocket->close(); 290 break ; 291 } 292 ui->label_2_info->setText("請等待---"); 293 ui->label_2_info->show(); 294 ui->progressBar_2_fingerImage->show(); 295 callFunc = 20; 296 } break; 297 298 case 4:{ //兩次指紋對比度 299 QByteArray buf = tcpSocket->readAll(); 300 QString str = QString(buf); 301 //解析返回值 302 QString check = QString(str).section("##", 0, 0); 303 QString score = QString(str).section("##", 1, 1); 304 tcpSocket->disconnectFromHost(); //關閉tcp 305 tcpSocket->close(); 306 307 if("True" != check) 308 return recCheck(check); 309 //檢驗合格 310 QMessageBox::information(this, "檢驗", QString("檢驗合格,分數:%1").arg(score)); 311 ui->pushButtonSure->setEnabled(true); 312 } break; 313 314 case 5:{ //存儲 315 QByteArray buf = tcpSocket->readAll(); 316 QString check = QString(buf); 317 tcpSocket->disconnectFromHost(); //關閉tcp 318 tcpSocket->close(); 319 320 if("True" != check) 321 return recCheck(check); 322 QMessageBox::information(this, "save", QString("儲存成功!")); 323 324 on_pushButtonConcel_clicked(); 325 326 } break; 327 328 case 6:{ // 接收占用指紋資源是否成功 329 QByteArray buf = tcpSocket->readAll(); 330 QString check = QString(buf); 331 tcpSocket->disconnectFromHost(); //關閉tcp 332 tcpSocket->close(); 333 334 if("True" != check) 335 return recCheck(check); 336 //開啟后使能和顯示提示 337 ui->label_2_info->show(); 338 ui->label_2_info->setText("開啟成功"); 339 ui->pushButtonSavefinger1->setEnabled(true); 340 ui->pushButton_2_Start->setText("關閉"); 341 } break; 342 343 case 7:{ // 接收釋放指紋資源是否成功 344 QByteArray buf = tcpSocket->readAll(); 345 QString check = QString(buf); 346 tcpSocket->disconnectFromHost(); //關閉tcp 347 tcpSocket->close(); 348 349 if("True" != check) 350 return recCheck(check); 351 QMessageBox::information(this, "release", QString("關閉成功!")); 352 //關閉后隱藏和禁止button 353 ui->label_2_info->hide(); 354 ui->progressBar_2_fingerImage->hide(); 355 ui->pushButton_2_Start->setText("開啟"); 356 357 } break; 358 359 case 8:{ // 獲取接收log 360 QByteArray buf = tcpSocket->readAll(); 361 QString check = QString(buf); 362 if("True" != check){ 363 tcpSocket->disconnectFromHost(); //關閉tcp 364 tcpSocket->close(); 365 return recCheck(check); 366 } 367 callFunc = 20; 368 369 } break; 370 371 case 9:{ // 查找人 372 QByteArray buf = tcpSocket->readAll(); 373 QString check = QString(buf); 374 if("True" != check){ 375 tcpSocket->disconnectFromHost(); //關閉tcp 376 tcpSocket->close(); 377 return recCheck(check); 378 } 379 callFunc = 20; 380 } break; 381 382 case 10:{ // 刪除人 383 QByteArray buf = tcpSocket->readAll(); 384 QString check = QString(buf); 385 if("True" != check){ 386 tcpSocket->disconnectFromHost(); //關閉tcp 387 tcpSocket->close(); 388 return recCheck(check); 389 } 390 QMessageBox::information(this, "刪除", QString("刪除成功!")); 391 } break; 392 393 case 11:{ // 備份數據庫 394 QByteArray buf = tcpSocket->readAll(); 395 QString check = QString(buf); 396 if("True" != check){ 397 tcpSocket->disconnectFromHost(); //關閉tcp 398 tcpSocket->close(); 399 return recCheck(check); 400 } 401 callFunc = 20; 402 } break; 403 404 case 12:{ // 上傳數據庫 405 QByteArray buf = tcpSocket->readAll(); 406 QString check = QString(buf); 407 if("True" != check){ 408 tcpSocket->disconnectFromHost(); //關閉tcp 409 tcpSocket->close(); 410 return recCheck(check); 411 } 412 qDebug() << buf; 413 sendDataFile(); 414 //callFunc = 21; 415 } break; 416 417 case 20:{ 418 recData(); 419 //顯示進度條 420 switch (recWhat){ 421 case 1:{ 422 ui->progressBar_1_get->setValue((100 * recvSize) / fileSize); 423 } break; 424 case 2:{ 425 ui->progressBar_2_fingerImage->setValue((100 * recvSize) / fileSize); 426 } break; 427 case 3:{ 428 ui->progressBar_2_fingerImage->setValue((100 * recvSize) / fileSize); 429 } break; 430 case 4:{ 431 } break; 432 case 5:{ 433 ui->progressBar_3_show->setValue((100 * recvSize) / fileSize); 434 } break; 435 default: break; 436 } 437 //傳輸完成后 438 if(showInfo == true) 439 { 440 showInfo = false; 441 callFunc = 0; 442 QMessageBox::information(this, "完成", "接收完成"); 443 switch (recWhat) { 444 case 1:{ 445 recWhat = 0; 446 ui->pushButton_1_get->setEnabled(true); 447 ui->progressBar_1_get->hide(); 448 } break; 449 case 2:{ 450 ui->pushButtonSavefinger2->setEnabled(true); 451 showImage = 2; 452 update(); 453 recWhat = 0; 454 } break; 455 case 3:{ 456 ui->pushButtoncheckfinger->setEnabled(true); 457 showImage = 2; 458 update(); 459 recWhat = 0; 460 } break; 461 case 4:{ 462 ui->textEdit_3_show->clear(); 463 QString str = showFile("find.txt"); 464 ui->textEdit_3_show->append(str); 465 ui->pushButton_3_find->setEnabled(true); 466 ui->lineEdit_3_findId->setEnabled(true); 467 ui->pushButton_3_delect->setEnabled(true); 468 recWhat = 0; 469 } break; 470 case 5:{ 471 ui->pushButton_3_back->setEnabled(true); 472 ui->progressBar_3_show->hide(); 473 recWhat = 0; 474 } break; 475 default: break; 476 } 477 } 478 } break; 479 480 481 case 21:{ // 發送文件 482 sendDataFile(); 483 } break; 484 485 // case 22:{ // 等待發送文件后的回應 486 // QByteArray buf = tcpSocket->readAll();; 487 // QString check = QString(buf).section("##", 0, 0); 488 // fileSize = QString(buf).section("##", 1, 1).toInt(); 489 // if("True" != check){ 490 // tcpSocket->disconnectFromHost(); //關閉tcp 491 // tcpSocket->close(); 492 // return recCheck(check); 493 // } 494 // callFunc = 23; 495 // } break; 496 497 // case 23:{ //等待對方更新完成 498 499 // } break; 500 501 default: break; 502 } 503 504 } 505 506 //獲取文件 507 void MainWindow::recData() 508 { 509 QByteArray buf = tcpSocket->readAll(); 510 QString check = QString(buf); 511 512 if(true == isStart) 513 { 514 qDebug() << buf; 515 isStart = false; 516 //解析傳回的頭文件 517 fileName = QString(buf).section("##", 0, 0); 518 fileSize = QString(buf).section("##", 1, 1).toInt(); 519 recvSize = 0; //初始化接收數據大小 520 521 qDebug() << fileName << fileSize; 522 if (0 == fileSize){ // 文件大小為0 523 tcpSocket->disconnectFromHost(); 524 tcpSocket->close(); 525 return recCheck("fileError"); 526 } 527 528 fileTransport.setFileName(fileName); 529 530 bool isOk = fileTransport.open(QIODevice::WriteOnly); 531 if(false == isOk) 532 { 533 qDebug() << "WriteOnly error 40"; 534 } 535 tcpSocket->write(QString("True").toUtf8().data()); 536 537 538 } 539 else 540 { 541 qint64 len = fileTransport.write(buf); 542 recvSize += len; 543 if(recvSize == fileSize) //判斷是否傳輸完成 544 { 545 fileTransport.close(); 546 tcpSocket->disconnectFromHost(); 547 tcpSocket->close(); 548 //准備新的傳輸 549 isStart = true; 550 showInfo = true; 551 } 552 } 553 } 554 555 //發送文件 556 void MainWindow::sendDataFile() 557 { 558 qint64 len = 0; 559 do 560 { 561 //每次發送數據的大小 562 char buf[4*1024] = {0}; 563 len = 0; 564 565 //往文件中讀數據 566 len = fileTransport.read(buf, sizeof(buf)); 567 568 //發送數據,讀多少,發多少 569 len = tcpSocket->write(buf, len); 570 //發送數據要累加 571 sendSize += len; 572 ui->progressBar_3_show->setValue(sendSize*100/upDateFileSize); 573 574 }while(len >0 ); 575 //是否發送文件完畢 576 if(sendSize == upDateFileSize) 577 { 578 QMessageBox::about(this, "傳輸", "文件發送完成"); 579 fileTransport.close(); 580 581 //把客戶端關閉 582 ui->textEdit_3_show->append("連接斷開"); 583 tcpSocket->disconnectFromHost(); 584 tcpSocket->close(); 585 586 587 ui->pushButton_3_Updata->setEnabled(true); 588 ui->pushButton_3_back->setEnabled(true); 589 ui->menuO->setEnabled(true); 590 ui->pushButton_3_find->setEnabled(true); 591 ui->progressBar_3_show->setValue(0); 592 ui->progressBar_3_show->hide(); 593 //callFunc = 22; 594 } 595 } 596 597 //接收的信號做檢測 598 void MainWindow::recCheck(QString check) 599 { 600 qDebug() << check; 601 if ("error" == check){// 連接失敗或者是登陸失敗 602 if(false == isLoad) 603 QMessageBox::warning(this, "連接信息", "用戶名或者密碼錯誤!"); 604 else 605 QMessageBox::warning(this, "連接信息", "連接斷開,重新登陸!"); 606 initData(); 607 } 608 else if("102" == check){// 沒有檢測到手指 609 ui->label_2_info->setText("請放入手指!"); 610 ui->label_2_info->show(); 611 switch (callFunc) { 612 case 2:{ 613 ui->pushButtonSavefinger1->setEnabled(true); 614 } break; 615 case 3:{ 616 ui->pushButtonSavefinger2->setEnabled(true); 617 }break; 618 default: break; 619 } 620 } 621 else if ("302" == check) { // 校驗失敗 622 QMessageBox::warning(this, "校驗信息", "兩次指紋不匹配!"); 623 this->on_pushButtonConcel_clicked(); 624 } 625 else if("link_error" == check) // 找不到服務器 626 { 627 QMessageBox::about(this, "連接信息", "連接失敗......"); 628 initData(); 629 } 630 else if("occupyError" == check) //搶占失敗 631 { 632 QMessageBox::about(this, "占用信息", "設備正忙......"); 633 isOccupy = false; 634 } 635 else if("getLogError" == check) 636 { 637 QMessageBox::about(this, "獲取日志", "失敗!"); 638 ui->progressBar_1_get->hide(); 639 ui->pushButton_1_get->setEnabled(true); 640 } 641 else if("findError" == check) 642 { 643 QMessageBox::about(this, "查找", "失敗!沒這個人"); 644 ui->pushButton_3_find->setEnabled(true); 645 ui->lineEdit_3_findId->setEnabled(true); 646 ui->textEdit_3_show->clear(); 647 } 648 else if("delectError" == check) 649 { 650 QMessageBox::about(this, "刪除", "刪除失敗!"); 651 } 652 else if("outPutError" == check) 653 { 654 QMessageBox::about(this, "導出數據庫", "導出失敗!"); 655 ui->pushButton_3_back->setEnabled(true); 656 } 657 else if("fileError" == check) 658 { 659 QMessageBox::about(this, "文件錯誤", "文件錯誤!"); 660 } 661 } 662 663 //繪圖事件 664 void MainWindow::paintEvent(QPaintEvent *) 665 { 666 667 QPainter p; 668 //QPaintDevice pD; 669 p.begin(this);//指定當前出窗口為繪圖設備 670 671 /* * 672 * showImage 673 * 1,顯示頁面顏色繪圖 674 * 2,指紋頁面繪圖 675 * 3,查詢頁面繪圖 676 * */ 677 switch (showImage) { 678 case 1: 679 // ui->pageShowInfo->setStyleSheet("#pageShowInfo{" 680 // "border-image:url(:/image/image/car.jpg);" 681 // "}" 682 // ); 683 // break; 684 685 case 2:{ 686 QString str = QString("QWidget{" 687 "border-image:url(finger.bmp);" 688 "}"); 689 ui->widgetFinger->setStyleSheet(str); 690 } 691 break; 692 693 case 3: 694 695 break; 696 697 default: 698 break; 699 } 700 701 p.end(); 702 } 703 704 //顯示文本 705 QString MainWindow::showFile(QString fileName) 706 { 707 QFile file(fileName); 708 ui->textEdit_1_Show->clear(); 709 bool isOk = file.open(QIODevice::ReadOnly); 710 if(false == isOk) 711 { 712 qDebug() << "WriteOnly error 40"; 713 } 714 QByteArray buff = file.readAll(); 715 QString str = QString(buff); 716 return str; 717 } 718 /***================= 菜單函數 ===================***/ 719 //顯示界面 720 void MainWindow::on_actionShow_triggered() 721 { 722 ui->stackedWidget->setCurrentWidget(ui->pageShowInfo); 723 showImage = 1; 724 update(); 725 726 } 727 728 //錄指紋界面 729 void MainWindow::on_actionSave_triggered() 730 { 731 ui->stackedWidget->setCurrentWidget(ui->pageSave); 732 showImage = 2; 733 update(); 734 } 735 736 //查找界面 737 void MainWindow::on_actionFind_triggered() 738 { 739 ui->stackedWidget->setCurrentWidget(ui->pageFind); 740 showImage = 3; 741 update(); 742 } 743 744 //菜單欄退出 745 void MainWindow::on_actionClose_triggered() 746 { 747 /***********連接服務器發送數據***********/ 748 callFunc = 20; 749 bool check = tcpLink(1); //不要默認模式 0 750 if(false == check) 751 { 752 MainWindow::close(); 753 } 754 } 755 756 /*** ===================界面登陸的函數========================== ***/ 757 //登陸函數 758 void MainWindow::on_pushButtonReg_clicked() 759 { 760 //禁止輸入 761 ui->lineEditUserName->setEnabled(false); 762 ui->lineEditPassward->setEnabled(false); 763 764 tcpSocket->disconnectFromHost(); 765 tcpSocket->close(); 766 //連接服務器 767 callFunc = 1; 768 tcpLink(); //默認模式 0 769 770 } 771 772 773 //退出函數 774 void MainWindow::on_pushButtonClose_clicked() 775 { 776 QMainWindow::close(); 777 } 778 779 //改變連接端口 780 void MainWindow::on_pB_logoChangelink_clicked() 781 { 782 if(false == isChangeLink) 783 { 784 isChangeLink = true; 785 ui->pB_logoChangelink->setText("返回?"); 786 //清楚編輯行文本 787 ui->lineEditUserName->clear(); 788 ui->lineEditPassward->clear(); 789 //設置端口和ip 790 ui->label_logo_name->setText("ip :"); 791 ui->label_logo_passwd->setText("port :"); 792 ui->lineEditPassward->setEchoMode(QLineEdit::Normal); //設置正常顯示 793 //隱藏登陸 794 ui->pushButtonReg->hide(); 795 796 qDebug() << ip << port; 797 } 798 else 799 { 800 isChangeLink = false; 801 ui->pB_logoChangelink->setText("更改登陸連接?"); 802 //設置端口和ip 803 ip = ui->lineEditUserName->text(); 804 port = ui->lineEditPassward->text().toInt(); 805 //清楚編輯行文本 806 ui->lineEditUserName->clear(); 807 ui->lineEditPassward->clear(); 808 //設置為登陸模式 809 ui->label_logo_name->setText("用戶名:"); 810 ui->label_logo_passwd->setText("密 碼:"); 811 ui->lineEditPassward->setEchoMode(QLineEdit::Password); 812 //顯示登陸 813 ui->pushButtonReg->show(); 814 815 qDebug() << ip << port; 816 } 817 } 818 /*** ===================界面1的函數========================== */ 819 //在窗口顯示信息 820 void MainWindow::on_pushButton_1_show_clicked() 821 { 822 QString str = showFile("log.txt"); 823 ui->textEdit_1_Show->append(str); 824 } 825 //下載更新log 826 void MainWindow::on_pushButton_1_get_clicked() 827 { 828 ui->pushButton_1_get->setEnabled(false); 829 //顯示進度條 830 ui->progressBar_1_get->setValue(0); 831 ui->progressBar_1_get->show(); 832 /***********連接服務器發送數據***********/ 833 recWhat = 1; 834 callFunc = 8; 835 tcpLink(); //默認模式 0 836 } 837 /*** ===================界面2的函數========================== */ 838 //開啟錄制,占用資源 839 void MainWindow::on_pushButton_2_Start_clicked() 840 { 841 if(false == isOccupy) //開啟占用 842 { 843 isOccupy = true; 844 /***********連接服務器發送數據***********/ 845 callFunc = 6; 846 //tcp連接 847 tcpLink(); 848 } 849 else // 釋放 850 { 851 isOccupy = false; 852 //禁止button 853 ui->pushButtonSavefinger1->setEnabled(false); 854 ui->pushButtonConcel->setEnabled(false); 855 ui->pushButtonSavefinger2->setEnabled(false); 856 ui->pushButtonSure->setEnabled(false); 857 ui->pushButtoncheckfinger->setEnabled(false); 858 //隱藏進度條 859 ui->progressBar_2_fingerImage->setValue(0); 860 ui->progressBar_2_fingerImage->hide(); 861 /***********連接服務器發送數據***********/ 862 callFunc = 7; 863 //tcp連接 864 tcpLink(); 865 } 866 } 867 868 //錄制指紋 1 Button 869 void MainWindow::on_pushButtonSavefinger1_clicked() 870 { 871 //使能返回button和禁止錄制button 872 ui->pushButtonSavefinger1->setEnabled(false); 873 ui->pushButtonConcel->setEnabled(true); 874 //禁止輸入 875 ui->lineEditname->setEnabled(false); 876 ui->lineEditID->setEnabled(false); 877 ui->lineEditdate->setEnabled(false); 878 //隱藏進度條 879 ui->progressBar_2_fingerImage->setValue(0); 880 ui->progressBar_2_fingerImage->hide(); 881 /***********連接服務器發送數據***********/ 882 callFunc = 2; 883 recWhat = 2; 884 tcpLink(); //默認模式 0 885 886 } 887 888 //錄制指紋 2 Button 889 void MainWindow::on_pushButtonSavefinger2_clicked() 890 { 891 //禁止button 892 ui->pushButtonSavefinger2->setEnabled(false); 893 //隱藏進度條 894 ui->progressBar_2_fingerImage->setValue(0); 895 ui->progressBar_2_fingerImage->hide(); 896 /***********連接服務器發送數據***********/ 897 callFunc = 3; 898 recWhat = 3; 899 tcpLink(); //默認模式 0 900 901 902 } 903 904 //檢驗兩次錄取准確度 905 void MainWindow::on_pushButtoncheckfinger_clicked() 906 { 907 ui->pushButtoncheckfinger->setEnabled(false); 908 /***********連接服務器發送數據***********/ 909 callFunc = 4; 910 tcpLink(); //默認模式 0 911 } 912 913 914 //取消錄取操作 915 void MainWindow::on_pushButtonConcel_clicked() 916 { 917 //開啟輸入 918 ui->lineEditname->setEnabled(true); 919 ui->lineEditID->setEnabled(true); 920 ui->lineEditdate->setEnabled(true); 921 //button功能轉換 922 ui->pushButtonSavefinger1->setEnabled(true); 923 ui->pushButtonConcel->setEnabled(false); 924 ui->pushButtonSavefinger2->setEnabled(false); 925 ui->pushButtonSure->setEnabled(false); 926 //隱藏顯示信息 927 ui->label_2_info->hide(); 928 ui->progressBar_2_fingerImage->hide(); 929 //關閉連接主機 930 tcpSocket->disconnectFromHost(); 931 tcpSocket->close(); 932 //關閉文件 933 fileTransport.close(); 934 isStart = true; 935 showInfo = false; 936 } 937 938 //更新數據庫 939 void MainWindow::on_pushButtonSure_clicked() 940 { 941 ui->pushButtonSure->setEnabled(false); 942 //彈出對話框提醒用戶是否更新 943 QString str = "是否跟新到數據庫"; 944 int isOk = QMessageBox::information(this, "issave", str, QMessageBox::Ok, QMessageBox::Cancel); 945 946 if (QMessageBox::Cancel == isOk) 947 { 948 on_pushButtonConcel_clicked(); 949 return; 950 } 951 952 // /*================== 數據庫的操作 ==============*/ 953 // //添加MySql數據庫 954 // QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); 955 // //連接數據庫 956 // db.setHostName("127.0.0.1"); //數據庫服務器IP 957 // db.setUserName("root"); //數據庫用戶名 958 // db.setPassword("123456"); //密碼 959 // db.setDatabaseName("myinfo"); //使用哪個數據庫 960 961 // //打開數據庫 962 // if(false == db.open()) //數據庫打開失敗 963 // { 964 // QMessageBox::warning(this, "錯誤", db.lastError().text()); 965 // return; 966 967 // } 968 969 // db.close(); 970 callFunc = 5; 971 tcpLink(); //默認模式 0 972 973 } 974 975 /*** ===================界面3的函數========================== */ 976 //查找人 977 void MainWindow::on_pushButton_3_find_clicked() 978 { 979 ui->pushButton_3_find->setEnabled(false); 980 ui->lineEdit_3_findId->setEnabled(false); 981 /***********連接服務器發送數據***********/ 982 callFunc = 9; 983 recWhat = 4; 984 tcpLink(); //默認模式 0 985 } 986 987 //刪除信息 988 void MainWindow::on_pushButton_3_delect_clicked() 989 { 990 ui->pushButton_3_delect->setEnabled(false); 991 /***********連接服務器發送數據***********/ 992 callFunc = 10; 993 tcpLink(); //默認模式 0 994 } 995 //輸入框變化 996 void MainWindow::on_lineEdit_3_findId_textChanged(const QString &arg1) 997 { 998 ui->pushButton_3_delect->setEnabled(false); 999 } 1000 1001 //備份數據庫 1002 void MainWindow::on_pushButton_3_back_clicked() 1003 { 1004 ui->pushButton_3_back->setEnabled(false); 1005 ui->progressBar_3_show->setValue(0); 1006 ui->progressBar_3_show->show(); 1007 /***********連接服務器發送數據***********/ 1008 callFunc = 11; 1009 recWhat = 5; 1010 tcpLink(); //默認模式 0 1011 1012 } 1013 //按查找的名字 1014 void MainWindow::on_pushButton_3_findName_clicked() 1015 { 1016 ui->lineEdit_3_findId->setEnabled(true); 1017 QString txt = ui->pushButton_3_findName->text(); 1018 if("查找id:" == txt) 1019 { 1020 ui->pushButton_3_findName->setText("查找name:"); 1021 findWhat = "name"; 1022 } 1023 else if("查找name:" == txt) 1024 { 1025 ui->pushButton_3_findName->setText("查找date:"); 1026 findWhat = "time"; 1027 } 1028 else if("查找date:" == txt) 1029 { 1030 ui->pushButton_3_findName->setText("查找all:"); 1031 findWhat = "id"; 1032 // ui->lineEdit_3_findId->setEnabled(false); 1033 } 1034 // else if("查找all:" == txt) 1035 // { 1036 // ui->pushButton_3_findName->setText("查找id:"); 1037 // findWhat = "id"; 1038 // } 1039 } 1040 1041 //上傳.sql 文件 並更新模塊 1042 void MainWindow::on_pushButton_3_Updata_clicked() 1043 { 1044 QString filePath = QFileDialog::getOpenFileName(this, "open", "./"); 1045 //如果路徑有效 1046 if(false == filePath.isEmpty()){ 1047 upDateFileName.clear(); // 上傳文件名字 1048 upDateFileSize = 0;//文件大小 1049 sendSize = 0; // 發送文件的大小 1050 //獲取信息 1051 QFileInfo info(filePath); 1052 upDateFileName = info.fileName(); 1053 upDateFileSize = info.size(); 1054 1055 //打開文件 1056 fileTransport.setFileName(filePath); 1057 bool isOk = fileTransport.open(QIODevice::ReadOnly); 1058 if(false == isOk){ 1059 qDebug() << "打開失敗 62"; 1060 } 1061 1062 ui->textEdit_3_show->setText(filePath); 1063 1064 ui->pushButton_3_Updata->setEnabled(false); 1065 ui->pushButton_3_back->setEnabled(false); 1066 ui->menuO->setEnabled(false); 1067 ui->pushButton_3_delect->setEnabled(false); 1068 ui->pushButton_3_find->setEnabled(false); 1069 ui->progressBar_3_show->setValue(0); 1070 ui->progressBar_3_show->show(); 1071 1072 } 1073 else{ 1074 qDebug() << "選擇文件路徑出錯 62"; 1075 1076 1077 } 1078 1079 1080 /***********連接服務器發送數據***********/ 1081 callFunc = 12; 1082 recWhat = 6; 1083 tcpLink(); //默認模式 0 1084 }
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 #include "QTcpServer" 6 #include "QTcpSocket" 7 #include "QPaintEvent" 8 9 namespace Ui { 10 class MainWindow; 11 } 12 13 class MainWindow : public QMainWindow 14 { 15 Q_OBJECT 16 17 public: 18 explicit MainWindow(QWidget *parent = 0); 19 ~MainWindow(); 20 21 //初始化數據 22 void initData(); 23 //初始化tcp 24 void initTcp(); 25 //設置tcp連接 26 bool tcpLink(int mode = 0); 27 28 //發送數據給服務器 29 void sendDataToServe(); 30 //處理接收的數據 31 void dealReceiveData(); 32 //接收文件 33 void recData(); 34 //處理接收的返回值檢測 35 void recCheck(QString check); 36 //畫圖事件 37 void paintEvent(QPaintEvent *); 38 //顯示文本 39 QString showFile(QString fileName); 40 //發送文件 41 void sendDataFile(); 42 43 signals: 44 void connectSuccess(); 45 46 private slots: 47 //菜單顯示事件 48 void on_actionShow_triggered(); 49 50 void on_actionSave_triggered(); 51 52 void on_actionFind_triggered(); 53 54 void on_actionClose_triggered(); // 菜單退出 55 56 //button事件 57 void on_pushButtonSavefinger1_clicked(); //錄指紋1 58 59 void on_pushButtonConcel_clicked(); //取消錄指紋 60 61 void on_pushButtonSure_clicked(); //確定錄取 62 63 void on_pushButtonReg_clicked(); //登陸服務器 64 65 void on_pushButtonClose_clicked(); //關閉窗口 66 67 void on_pushButtonSavefinger2_clicked(); //錄制指紋 2 68 69 void on_pushButtoncheckfinger_clicked(); //檢驗兩次錄取准確度 70 71 void on_pB_logoChangelink_clicked(); // 登陸界面改變link 72 73 void on_pushButton_2_Start_clicked(); //申請資源 74 75 void on_pushButton_1_get_clicked(); //獲取日志 76 77 void on_pushButton_1_show_clicked(); //顯示日志 78 79 void on_pushButton_3_find_clicked(); //查找人 80 81 void on_lineEdit_3_findId_textChanged(const QString &arg1); 82 83 void on_pushButton_3_delect_clicked(); //刪除信息 84 85 void on_pushButton_3_back_clicked(); //備份數據庫 86 87 void on_pushButton_3_findName_clicked(); // 更改查找選項 88 89 void on_pushButton_3_Updata_clicked(); // 上傳數據庫 90 91 private: 92 Ui::MainWindow *ui; 93 94 //tcp套接字指針 95 QTcpSocket *tcpSocket; 96 QString ip; 97 quint16 port; 98 99 int showImage; //顯示哪個界面 100 bool isLoad; //是否登陸 101 bool isChangeLink; 102 int recWhat; //接收的什么數據 103 bool isOccupy; //是否占用指紋資源 104 /* * 105 * 哪個函數發送的tcp請求 106 * 1,登陸 107 * */ 108 int callFunc; 109 110 QString filePath; //文件路徑 111 QFile fileTransport;//文件對象 112 QString fileName;//文件名字 113 qint64 fileSize;//文件大小 114 qint64 recvSize;//已經發送的文件的大小 115 bool isStart; //接收頭文件 116 bool showInfo; //接收完成后 117 118 QString upDateFileName; // 上傳文件名字 119 qint64 upDateFileSize;//文件大小 120 qint64 sendSize; // 發送文件的大小 121 122 QString findWhat; //按什么查找數據庫 123 }; 124 125 #endif // MAINWINDOW_H
3.然后就是數據庫儲存了
就是一些簡單的mysql語句
1 #!/usr/local/opt/python-3.5.2/bin/python3.5 2 #-*- coding:utf8 -*- 3 4 import pymysql 5 import os, sys 6 import configparser 7 8 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 9 sys.path.append(PATH) 10 11 from core import dealFile 12 13 14 class mySqlDeal: 15 """數據庫的操作""" 16 def __init__(self, cmd=None, data=None, host="127.0.0.1", port=3306, user="root", passwd="123456", db="finger", table="test"): 17 cf = configparser.ConfigParser() 18 cf = dealFile.readConf(cf) 19 host = cf.get("db", "db_host") 20 port = cf.getint("db", "db_port") 21 user = cf.get("db", "db_user") 22 passwd = cf.get("db", "db_pwd") 23 db = cf.get("db", "db_database") 24 table = cf.get("db", "db_table") 25 """初始化數據""" 26 self.cmd = cmd 27 self.data = data 28 self.host = host 29 self.port = port 30 self.user = user 31 self.passwd = passwd 32 self.db = db 33 self.table = table 34 pass 35 36 def link(self): 37 """連接數據庫""" 38 self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.db) 39 self.cursor = self.conn.cursor() 40 pass 41 42 def run(self, cmd=None, table=None): 43 """執行cmd""" 44 self.link() 45 if hasattr(self, self.cmd): 46 func = getattr(self, self.cmd) 47 return func(data=self.data, table=self.table) 48 self.endSql() 49 return False, None 50 51 def creatDatabase(self, data, table): 52 """創建數據庫""" 53 pass 54 55 def creatTable(self, data, table): 56 """創建表""" 57 pass 58 59 def insertData(self, data, table): 60 """插入數據到數據庫""" 61 if isinstance(data, dict) is not True: # 判斷data是不是字典類型 62 return False, None 63 # 拼接sql語句 執行 64 sqlStr = "INSERT INTO {table} VALUES ('{num}', '{id}', '{name}', '{date}', '{finger}');"\ 65 .format(table=table, num=data['num'], id=data["id"], name=data["name"], date=data["date"], finger=data["finger"]) 66 self.cursor.execute(sqlStr) 67 68 self.endSql() # 結束sql 69 return True, None 70 pass 71 72 def selectAll(self, data=None, table=None): 73 """選擇數據庫中的數據 所有""" 74 # 拼接sql語句 執行 75 sqlStr = "SELECT * FROM {table};".format(table=table) 76 self.cursor.execute(sqlStr) 77 data = self.cursor.fetchall() # 尋找所有數據 78 79 self.endSql() # 結束sql 80 return True, data 81 pass 82 83 def selectData(self, data=None, table=None): 84 """選擇數據庫中的數據""" 85 # 拼接sql語句 執行 86 data = data.split(":") 87 sqlStr = "SELECT * FROM {table} WHERE {what}={find};".format(table=table, what=data[0], find=data[1]) 88 self.cursor.execute(sqlStr) 89 data = self.cursor.fetchall() # 尋找所有數據 90 91 self.endSql() # 結束sql 92 return True, data 93 pass 94 95 def selectId(self, data, table): 96 """ 97 :param data: 固定格式必須要 what:find 98 :param table: 99 :return: 100 """ 101 # 拼接sql語句 執行 102 data = data.split(":") 103 if data[0] == "all": 104 sqlStr = "SELECT id, name, time FROM {table};".format(table=table) 105 else: 106 sqlStr = "SELECT id, name, time FROM {table} WHERE {what} REGEXP '^{find}';"\ 107 .format(table=table, what=data[0], find=data[1]) 108 self.cursor.execute(sqlStr) 109 data = self.cursor.fetchall() # 尋找所有數據 110 self.endSql() # 結束sql 111 if len(data) is 0: 112 return False, None 113 return True, data 114 115 def selectNum(self, data, table): 116 data = data.split(":") 117 sqlStr = "SELECT num FROM {table} WHERE {what} REGEXP '^{find}';"\ 118 .format(table=table, what=data[0], find=data[1]) 119 self.cursor.execute(sqlStr) 120 data = self.cursor.fetchall() # 尋找所有數據 121 self.endSql() # 結束sql 122 if len(data) is 0: 123 return False, None 124 return True, data 125 pass 126 127 def delectId(self, data, table): 128 """ 129 :param data: 固定格式必須要 what:find 130 :param table: 131 :return: 132 """ 133 # 拼接sql語句 執行 134 data = data.split(":") 135 if data[0] == "all": 136 sqlStr = "DELETE FROM {table};".format(table=table) 137 else: 138 sqlStr = "DELETE FROM {table} WHERE {what} REGEXP '^{find}';".format(table=table, what=data[0], find=data[1]) 139 self.cursor.execute(sqlStr) 140 self.endSql() # 結束sql 141 return True, None 142 143 def endSql(self): 144 145 """提交和關閉sql""" 146 self.conn.commit() 147 self.cursor.close() 148 self.conn.close() 149 150 pass 151 152 153 if __name__ == "__main__": 154 # delectId 155 # A = mySqlDeal("selectWhat", "name") 156 A = mySqlDeal("selectId", "name:12") 157 check, data = A.run() 158 # print(check) 159 # for i in data: 160 # print(i) 161 print(check) 162 print(data) 163 164 pass
4.可以用Pycharm遠程調試樹莓派啦
網上有很多遠程調試的例子,如果還是不會可以留言
首先用編寫打卡的程序,用到樹莓派GPIO口
1 # -*- coding:utf8 -*- 2 3 import RPi.GPIO as GPIO 4 5 import os,sys 6 7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 sys.path.append(PATH) 9 # import core 10 from core.dealSql import mySqlDeal 11 from core import dealFinger 12 # from core import clockIn 13 from core import dealFile 14 from core import oledshow 15 # from core import Tcpserver 16 import time 17 18 isOccupy = False 19 20 class ClockCheck: 21 22 def __init__(self, queueOled, queueToTcp, queueToClock, queueIsNewSql): 23 self.flage = False 24 self.queueOled = queueOled 25 self.queueToTcp = queueToTcp 26 self.queueToClock = queueToClock 27 self.queueIsNewSql = queueIsNewSql 28 """初始化GPIO""" 29 self.GPIO_Pin = 18 30 GPIO.setmode(GPIO.BCM) 31 GPIO.setwarnings(False) 32 GPIO.setup(self.GPIO_Pin, GPIO.IN) 33 """引入其他模塊""" 34 # self.mysql = mySqlDeal() 35 self.myFinger = dealFinger.DealFinger() 36 self.check = 0 37 38 # check, self.data = self.mysql.run() 39 pass 40 41 def run(self): 42 while True: 43 """判斷是否串口可用""" 44 check = self.isOk() 45 if check is not True: 46 continue 47 """獲取數據庫的值""" 48 self.flage = True 49 50 a = time.time() 51 check = self.getChar() # 判斷是否獲取成功 52 if check is not True: 53 print(check) 54 self.release() 55 continue 56 """判斷是否有指紋存在""" 57 check = self.checkFinger(0) 58 self.release() 59 print(time.time() - a) 60 if check is not True: 61 print("ERROR") 62 continue 63 print("success!") 64 pass 65 66 def isOk(self): 67 """判斷是否串口可用""" 68 if GPIO.input(self.GPIO_Pin) is GPIO.LOW: 69 if self.queueIsNewSql.empty() is not True: # 是否跟新數據 70 self.queueIsNewSql.get() 71 self.renewData() 72 """判斷是否有指紋按下""" 73 if self.flage is True: 74 self.flage = False 75 return False 76 """有指紋按下判斷是否可搶占""" 77 check = self.occupy() 78 if check is not True: 79 return False 80 81 if self.check is 102: # 清除沒指紋意外 82 self.check = 0 83 self.flage = False 84 if self.flage is not False: 85 self.release() # 釋放 86 return False 87 return True 88 pass 89 90 def occupy(self): 91 """搶占指紋資源""" 92 global isOccupy 93 if self.queueToClock.empty() is not True: 94 isOccupy = self.queueToClock.get() 95 96 if isOccupy is True: 97 # print("occupyError") 98 return False 99 self.queueToTcp.put(1) 100 return True 101 pass 102 103 def release(self): 104 """釋放指紋資源""" 105 self.queueToTcp.put(0) 106 107 def renewData(self): 108 # check, self.data = self.mysql.run() 109 # return check 110 pass 111 112 def checkFinger(self, data): 113 """和數據庫中的指紋匹配""" 114 self.myFinger.link() 115 check, buff = self.myFinger.checkPSIdentify() 116 if check is True: 117 """獲取數據庫中的相應值""" 118 num = buff[1]*256 + buff[2] 119 numStr = "num:%s" % num 120 print(numStr) 121 mysql = mySqlDeal("selectData", numStr) 122 check, data = mysql.run() 123 for i in data: 124 fingerData = eval(i[4]) 125 fingerData = dealFinger.DealBuff(fingerData) 126 fingerData = fingerData.write() 127 check, score = self.myFinger.isFinger(fingerData) 128 if check is True: 129 self.writeLog(i[1] + " " + i[2], "log.txt") 130 qDir ={ 131 "check": True, 132 "id": i[1], 133 "name": i[2] 134 } 135 self.queueOled.put(qDir) 136 time.sleep(0.2) 137 return True 138 print(check) 139 qDir = { 140 "check": False 141 } 142 self.queueOled.put(qDir) 143 time.sleep(0.2) 144 return False 145 146 def writeLog(self, data, fileName): 147 date = time.strftime("%Y-%m-%d %X ") 148 data = date + data + "\r\n\r\n" 149 dealFile.textLog(data, fileName) 150 pass 151 152 def getChar(self): 153 """獲取現在按下的指紋的信息""" 154 self.myFinger.link() 155 check = self.myFinger.getImage() # 檢測獲取圖像 156 if check is not True: 157 self.check = check 158 return check 159 160 self.myFinger.link() 161 check = self.myFinger.genChar("1") # 檢測生成特征值 放如模塊1 162 if check is not True: 163 return check 164 165 return True 166 pass 167 168 169 if __name__ == "__main__": 170 import core 171 A = ClockCheck(core.qOledClock, core.qToTcpOccupy, core.qToClockOccupy, core.qIsNewSql) 172 A.run() 173 pass
當能夠正常打卡后就需要在液晶屏上顯示了
1 import time 2 import Adafruit_GPIO.SPI as SPI 3 import Adafruit_SSD1306 4 from PIL import Image, ImageDraw, ImageFont 5 6 import os, sys 7 8 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 9 sys.path.append(PATH) 10 11 path = PATH + "/static/" 12 13 # 引腳配置,按照上面的接線來配置 14 RST = 17 15 DC = 27 16 # 因為連的是CE0,這里的PORT和DEVICE也設置為0 17 SPI_PORT = 0 18 SPI_DEVICE = 0 19 disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000)) 20 class Oled: 21 """oled顯示""" 22 def __init__(self, queue): 23 self.queue = queue 24 # 根據自己的oled型號進行初始化,我的是128X64、SPI的oled,使用SSD1306_128_64初始化 25 self.disp = disp 26 self.disp.begin() 27 self.disp.clear() 28 self.disp.display() 29 self.width = self.disp.width 30 self.height = self.disp.height 31 # image ,顯示一些文字 32 self.image = Image.new('1', (self.width, self.height)) 33 self.draw = ImageDraw.Draw(self.image) 34 35 self.fontDate = ImageFont.truetype(path + "simsun.ttc", 16) 36 self.fontTime = ImageFont.truetype(path + "EXEPixelPerfect.ttf", 50) 37 self.fontNum = ImageFont.truetype(path + "EXEPixelPerfect.ttf", 35) 38 self.fontName = ImageFont.truetype(path + "simsun.ttc", 28) 39 pass 40 41 def run(self): 42 """顯示界面""" 43 while True: 44 date = time.ctime() 45 date = date.split(" ") 46 num = len(date) # 當日期小於10時 日期為" num" 大於10為"num" 47 self.draw.text((0, 0), date[0], font=self.fontDate, fill=1) # 星期幾 48 if num == 6: 49 self.draw.text((80, 0), date[1] + " " + date[3], font=self.fontDate, fill=1) # 月份 50 else: 51 self.draw.text((80, 0), date[1] + " " + date[2], font=self.fontDate, fill=1) # 月份 52 self.draw.text((0, 20), date[-2], font=self.fontTime, fill=1) # 時間 53 """顯示""" 54 self.disp.image(self.image) 55 self.disp.display() 56 """清屏""" 57 self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0) 58 """顯示""" 59 self.showPeple() 60 61 pass 62 63 def showPeple(self): 64 """顯示人""" 65 if self.queue.empty() is True: # 沒有人按 66 # time.sleep(0.2) 67 return 68 data = self.queue.get() 69 if data["check"] is False: # 有人按匹配錯誤 70 self.draw.text((15, 20), "ERROR", font=self.fontTime, fill=1) 71 """顯示""" 72 self.disp.image(self.image) 73 self.disp.display() 74 """清屏""" 75 self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0) 76 time.sleep(2) 77 return 78 self.draw.text((0, 0), data["id"], font=self.fontNum, fill=1) 79 self.draw.text((25, 30), data["name"], font=self.fontName, fill=1) 80 """顯示""" 81 self.disp.image(self.image) 82 self.disp.display() 83 """清屏""" 84 self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0) 85 time.sleep(2) 86 pass 87 88 pass 89 90 91 if __name__ == "__main__": 92 from multiprocessing import Queue 93 q = Queue() 94 A = Oled(q) 95 A.run()
5.怎么實現物聯呢
這就要用到公網平台了,應為我們都是“私網”,
剛開始想用yeelink的,但是發現好像沒人維護用不了了,我就發現了“樂為物聯”這個平台,操作簡單
你首先得在上面注冊一個用戶,他上面有api的介紹,很容易看懂
再分享一波
我是想在微信上發送命令
1 # -*- coding:utf8 -*- 2 3 import configparser 4 from core import dealFile 5 from core import emailSendReceive 6 7 import optparse 8 import os, sys 9 import socket 10 import json,re 11 import time 12 13 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 14 sys.path.append(PATH) 15 16 cf = configparser.ConfigParser() 17 cf = dealFile.readConf(cf) 18 ip = cf.get("lewei", "ip") 19 port = cf.getint("lewei", "port") 20 userKey = cf.get("lewei", "userKey") 21 gatewayNode = cf.get("lewei", "gatewayNode") 22 23 24 # ip = "tcp.lewei50.com" 25 # port = 9960 26 # userKey = "9701daf039574b199602b4958252dc19" 27 # gatewayNode = "02" 28 29 head = "&^!" 30 31 class ClientHandler(): 32 33 def __init__(self): 34 35 self.bufsize = 1024 36 # self.op = optparse.OptionParser() 37 # option,args = self.op.parse_args() 38 # 39 # self.verify_args(option,args) 40 self.connect() 41 42 def verify_args(self,option,args): 43 '啟動命令處理' 44 cmd = args[0] 45 if hasattr(self,cmd): 46 func = getattr(self,cmd) 47 func() 48 else: 49 exit("No parameter") 50 51 def connect(self): 52 '連接網路' 53 self.loadToServer() 54 oldTime = time.time() 55 while True: 56 nowTime = time.time() 57 if nowTime - oldTime > 40: 58 oldTime = nowTime 59 self.loadToServer() 60 self.interactive() 61 62 def interactive(self): 63 self.rev_deal() 64 65 def loadToServer(self): 66 '發送數據登陸服務器' 67 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 68 self.sock.connect((ip, port)) 69 cmd={ 70 'method': "update", 71 'gatewayNo': gatewayNode, 72 'userkey': userKey 73 } 74 self.sendData(cmd) 75 76 def rev_deal(self): 77 '處理接收的數據做命令分類' 78 """調用該命令時會調用該設備的API地址傳遞參數f=方法名,p1=參數1,p2=參數2......""" 79 data = self.sock.recv(self.bufsize).decode("gbk") 80 if data: 81 print(data) 82 data = re.split("[&^!]", data) # 去掉數據尾巴 83 data = eval(data[0]) # 轉換成字典 84 self.data = data 85 # print(data) 86 if hasattr(self, data["f"]): 87 func = getattr(self, data["f"]) 88 func() 89 90 """======================================= f = message ===========================================""" 91 def message(self): 92 print("message") 93 pass 94 95 """======================================= f = sendemail ===========================================""" 96 def sendEmail(self): 97 data = str.lower(self.data["p1"]) 98 if data: 99 if hasattr(self, data): 100 func = getattr(self, data) 101 func() 102 self.sendSuccess() 103 pass 104 105 def getlog(self): 106 """得到日志""" 107 a = emailSendReceive.SendEmail() 108 a.run(self.data["p1"]) 109 self.sendSuccess() 110 pass 111 112 def backlog(self): 113 """備份日志""" 114 backname = "log_{date}.txt".format(date=time.strftime("%Y.%m.%d.%X")) 115 dealFile.backFile("log.txt", backname) 116 pass 117 118 def getlogall(self): 119 """得到所有日志""" 120 a = emailSendReceive.SendEmail() 121 a.run(self.data["p1"]) 122 self.sendSuccess() 123 pass 124 125 def clean(self): 126 """清除所有日志""" 127 dealFile.cleanFile() # 清除日志 128 pass 129 130 """======================================= f = getAllSensors ===========================================""" 131 def getAllSensors(self): 132 '上傳傳感器數據給服務器,讓它知道傳感器狀態' 133 data={ 134 "method": "response", 135 "result":{ 136 "successful": True, 137 "message": "xxxx", 138 "data":[{ 139 "id": "POWER", 140 "value": 0 141 }, 142 { 143 "id": "ledLight", 144 "value": 0 145 } 146 ] 147 } 148 } # 固定格式 149 self.sendData(data) 150 151 """========================================= f = updateSensor ==============================================""" 152 def updateSensor(self): 153 '區分傳感器標識' 154 data = str.lower(self.data["p1"]) 155 if data: 156 if hasattr(self, data): 157 func = getattr(self, data) 158 func() 159 160 def power(self): 161 '傳感器power標識' 162 if self.data["p2"] == "1": 163 self.sendSuccess() 164 # conf.LED_STATUS = 1 165 print("open led") 166 elif self.data["p2"] == "0": 167 self.sendSuccess() 168 # conf.LED_STATUS = 0 169 print("close led") 170 171 def ledlight(self): 172 '傳感器ledlignt標識' 173 self.sendSuccess() 174 # conf.LED_VALUE = self.data["p2"] 175 print("led亮度為",self.data["p2"]) 176 177 def sendSuccess(self): 178 '返回接收數據成功' 179 data = { 180 "method": "response", 181 "result": 182 { 183 "successful": True, 184 "message": "發送成功!" 185 } 186 } 187 self.sendData(data) 188 189 def sendData(self,data): 190 data = json.dumps(data) 191 data += head 192 self.sock.send(data.encode("gbk")) 193 194 195 196 if __name__ == '__main__': 197 ch = ClientHandler() 198 # cd F:\tmp\python_date1\myDevice\bin 199 # python tcp_client.py connect
如果你不想在注冊或者嫌麻煩也可以通過郵箱來發送命令
郵箱的代碼在下面
1 # -*- coding:utf8 -*- 2 3 import smtplib 4 from poplib import POP3_SSL 5 from email.parser import Parser 6 from email.header import Header 7 from email.mime.text import MIMEText 8 from email.mime.multipart import MIMEMultipart 9 from email.utils import formataddr 10 11 from core import dealFile 12 import time 13 import configparser 14 import os, sys 15 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 16 17 18 cf = configparser.ConfigParser() 19 cf = dealFile.readConf(cf) 20 21 smtpServer = cf.get("email", "smtpServer") # 發送請求服務 22 popServer = cf.get("email", "popServer") # 接收請求服務 23 24 # smtpSrcAddr = "270176392@qq.com" # 發送的源郵箱 25 # smtpSrcAddrPwd = "tromtljvidhgbibj" # 發送源郵箱的請求碼 密碼 26 smtpSrcAddr = cf.get("email", "smtpSrcAddr") 27 smtpSrcAddrPwd = cf.get("email", "smtpSrcAddrPwd") 28 29 smtpDstAddr = cf.get("email", "smtpDstAddr") # 發送的目的郵箱 30 smtpPort = cf.get("email", "smtpPort") 31 32 33 34 def sendEmailTxt(msg): 35 """發送文本內容""" 36 massage = MIMEText(msg, "plain", "utf8") 37 return massage 38 39 40 def sendEmailFile(filename): 41 """發送附件""" 42 fileName = dealFile.getFilePath(filename) 43 massage = MIMEText(open(fileName).read(), "base64", "utf8") 44 massage['Content-Type'] = "application/octet-stream" 45 massage['Content-Disposition'] = "attachment; filename = {name}".format(name=filename) 46 return massage 47 48 49 class SendEmail: 50 """發送郵件類""" 51 def __init__(self): 52 """初始化""" 53 self.massage = MIMEMultipart() 54 self.massage['From'] = formataddr(["實驗室", smtpSrcAddr]) 55 self.massage['To'] = formataddr(["to", smtpDstAddr]) 56 self.massage['Subject'] = Header("回復郵件", "utf8") 57 self.server = smtplib.SMTP_SSL(smtpServer, smtpPort) 58 pass 59 60 def run(self, cmd): 61 """解析命令""" 62 if isinstance(cmd, str): 63 if hasattr(self, cmd): 64 cmd = cmd.lower() 65 func = getattr(self, cmd) 66 func() 67 self.login(self.massage) 68 self.quit() 69 elif isinstance(cmd, list): 70 for i in cmd: 71 if hasattr(self, i): 72 i = i.lower() 73 func = getattr(self, i) 74 func() 75 if len(self.massage.get_payload())is 0: 76 return self.quit() 77 self.login(self.massage) 78 self.quit() 79 pass 80 81 def getlog(self): 82 """得到日志""" 83 sendStr = "{date} 最新日志\r\n".format(date=time.strftime("%Y-%m-%d")) 84 massage = sendEmailTxt(sendStr) 85 self.massage.attach(massage) 86 massage = sendEmailFile("log.txt") 87 print(massage) 88 self.massage.attach(massage) 89 pass 90 91 def backlog(self): 92 """備份日志""" 93 backname = "log_{date}.txt".format(date=time.strftime("%Y.%m.%d.%X")) 94 dealFile.backFile("log.txt", backname) 95 sendStr = "備份成功\r\n" 96 massage = sendEmailTxt(sendStr) 97 self.massage.attach(massage) 98 pass 99 100 def getlogall(self): 101 """得到所有日志""" 102 dealFile.joinFile() # 拼接所有日志 103 104 sendStr = "{date} 前的所有日志\r\n".format(date=time.strftime("%Y-%m-%d")) 105 massage = sendEmailTxt(sendStr) 106 self.massage.attach(massage) 107 massage = sendEmailFile("logback.txt") 108 print(massage) 109 self.massage.attach(massage) 110 pass 111 112 def help(self): 113 """幫助文檔""" 114 sendStr = "幫助文檔!\r\n" 115 massage = sendEmailTxt(sendStr) 116 self.massage.attach(massage) 117 massage = sendEmailFile("help.txt") 118 print(massage) 119 self.massage.attach(massage) 120 pass 121 122 def clean(self): 123 """清除所有日志""" 124 dealFile.cleanFile() # 清除日志 125 126 sendStr = "清除成功!\r\n" 127 massage = sendEmailTxt(sendStr) 128 self.massage.attach(massage) 129 pass 130 131 def login(self, msg): 132 """登陸發送""" 133 self.server.login(smtpSrcAddr, smtpSrcAddrPwd) 134 self.server.sendmail(smtpSrcAddr, smtpDstAddr, msg.as_string()) 135 pass 136 137 def quit(self): 138 """退出""" 139 self.server.quit() 140 pass 141 pass 142 143 144 class GetEmail: 145 """獲取郵件並解析""" 146 def __init__(self): 147 self.server = POP3_SSL(popServer) 148 pass 149 150 def run(self): 151 152 self.login() 153 cmd = self.getEmail() 154 self.deleEmail() 155 self.quit() 156 return cmd 157 158 def getEmail(self): 159 """獲取最新消息""" 160 num, size = self.server.stat() 161 if num > 0: 162 resp, list, octets = self.server.retr(num) 163 """分開list, 將信息變為emailMassger""" 164 msg = b"\r\n".join(list).decode("utf8") 165 msg = Parser().parsestr(msg) 166 """解析出命令""" 167 cmd = self.analyze(msg) 168 try: 169 cmd = cmd.split(",") 170 return cmd 171 except Exception as e: 172 print(e) 173 return False 174 pass 175 176 def deleEmail(self): 177 num, size = self.server.stat() 178 if num > 0: 179 for i in range(num): 180 self.server.dele(i+1) 181 pass 182 183 def analyze(self, msg): 184 """解析出msg中的文本內""" 185 if msg.is_multipart(): 186 print("is_multipart") 187 parts = msg.get_payload() 188 part = parts[0] # 得到第一個 189 content = part.get_payload(decode=True) 190 charset = self.gussCharset(part) # 得到編碼格式 191 if charset: 192 content = content.decode(charset) 193 return content 194 else: 195 print("is_not_multipart") 196 content_type = msg.get_content_type() 197 if content_type == 'text/plain' or content_type == 'text/html': 198 content = msg.get_payload(decode=True) 199 charset = self.gussCharset(msg) # 得到編碼格式 200 if charset: 201 content = content.decode(charset) 202 return content 203 else: 204 print("Attachment.........................") 205 pass 206 207 def gussCharset(self, msg): 208 """獲取編碼格式""" 209 charset = msg.get_charset() 210 if charset is None: 211 content_type = msg.get("Content-Type", "").lower() 212 pos = content_type.find("charset=") 213 if pos > 0: 214 charset = content_type[pos+8:] 215 return charset 216 pass 217 218 def login(self): 219 self.server.user(smtpSrcAddr) 220 self.server.pass_(smtpSrcAddrPwd) 221 pass 222 223 def quit(self): 224 self.server.quit() 225 pass 226 227 pass 228 229 230 if __name__ == "__main__": 231 while True: 232 A = GetEmail() 233 cmd = A.run() 234 print(cmd) 235 time.sleep(10) 236 if cmd is not False: 237 B = SendEmail() 238 B.run(cmd) 239 time.sleep(10) 240 pass
6.最后看看主程序把
分別寫兩個腳本運行就好了
1 # -*- coding:utf8 -*- 2 3 import os,sys 4 import socketserver 5 import threading 6 import time 7 from multiprocessing import Process 8 9 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 10 sys.path.append(PATH) 11 12 from core import Tcpserver 13 from core import clockIn 14 from core import oledshow 15 from core import emailSendReceive 16 from core import dealFile 17 import configparser 18 import core 19 20 def TCP(): 21 """tcp進程""" 22 # check = threading.Thread(target=Tcpserver.checkOccupy) 23 # check.start() 24 cf = configparser.ConfigParser() 25 cf = dealFile.readConf(cf) 26 ip = cf.get("TCP", "ip") 27 port = cf.getint("TCP", "port") 28 ip_port = (ip, port) 29 print("----等待連接.............") 30 s = socketserver.ThreadingTCPServer(ip_port, Tcpserver.SeverHandle) 31 s.serve_forever() 32 pass 33 34 35 def CLOCK(queueOled, queueToTcp, queueToClock, queueIsNewSql): 36 """檢驗進程""" 37 gpio = clockIn.ClockCheck(queueOled, queueToTcp, queueToClock, queueIsNewSql) 38 gpio.run() 39 pass 40 41 42 def OLED(queue): 43 """oled進程""" 44 oled = oledshow.Oled(queue) 45 oled.run() 46 pass 47 48 49 def EMAIL(): 50 """郵件進程""" 51 while True: 52 A = emailSendReceive.GetEmail() 53 cmd = A.run() 54 print(cmd) 55 time.sleep(10) 56 if cmd is not False: 57 B = emailSendReceive.SendEmail() 58 B.run(cmd) 59 time.sleep(10) 60 61 62 def main(): 63 # A = Process(target=TCP) 64 # B = Process(target=EMAIL) 65 C = threading.Thread(target=CLOCK, args=(core.qOledClock, core.qToTcpOccupy, core.qToClockOccupy, core.qIsNewSql)) 66 D = threading.Thread(target=OLED, args=(core.qOledClock,)) 67 68 # A.start() 69 # B.start() 70 C.start() 71 D.start() 72 # A.join() 73 TCP() 74 75 76 if __name__ == "__main__": 77 main() 78 # TCP()
1 # -*- coding:utf8 -*- 2 3 from core import weChat 4 5 def main(): 6 a = weChat.ClientHandler() 7 8 9 if __name__ == "__main__": 10 main() 11 # TCP()
邏輯結構圖如下

未經本人許可不得轉載 謝謝!!!
