socket编程-多个客户端向服务器发送人脸照片,服务器返回识别结果(服务器使用多线程)
recognition.py
import numpy as np import face_recognition import os class recognition: def __init__(self): file_handle = open('picture_name.txt', 'r') nameStr = file_handle.readline().strip() self.total_image_name = nameStr.split(' ') file_handle.close() codeArray = np.loadtxt('picture_encode.txt') self.total_face_encoding = list(codeArray) def startRecog(self, path): image_code_list, numOfImages = self.readImage(path) if numOfImages != 3: return 'failed' else: #3.进行识别,将识别结果保存在一个字符串列表中 result_list = [] for i in range(numOfImages): for k, v in enumerate(self.total_face_encoding): match = face_recognition.compare_faces([v], image_code_list[i][0], tolerance=0.5) name = 'unknown' if match[0]: name = self.total_image_name[k] result_list.append(name) break #4.如果数组中有两个相同的元素,就将该元素返回给客户端 print(result_list) item1 = result_list[0] item2 = result_list[1] item3 = result_list[2] if item1 == item2 and item1 == item3 and item1 != 'unknown': return item1 elif (item1 == item2 and item1 != 'unknown') or (item1 == item3 and item1 != 'unknown'): return item1 elif item2 == item3 and item2 != 'unknown': return item2 else: return 'failed' def readImage(self, path): image_code_List = [] imageList = os.listdir(path) for image in imageList: newPath = path + '/' + image image_code_List.append(face_recognition.face_encodings(face_recognition.load_image_file(newPath))) return image_code_List, len(imageList)
服务器端:
import socket import threading import os import recognition class recogServer: def __init__(self): print('启动服务') self.sock = socket.socket() #创建socket self.addr = ('127.0.0.1',9999) #服务器要绑定的IP和端口 self.sock.bind(self.addr) #绑定IP和端口 有一个端口已占用的问题 self.clients = {} self.recognition = recognition.recognition() def start(self): self.sock.listen() accept_thread = threading.Thread(target=self.accept, name='accpet_thread') accept_thread.start() def accept(self): while True: s, raddr = self.sock.accept() self.clients[raddr] = s recv_thread = threading.Thread(target=self.recv, name='recv_thread', args=(s, raddr)) recv_thread.start() def recv(self, s, raddr): clientStr = raddr[0] + '-' + str(raddr[1]) clientDir = 'recvImage/' + clientStr self.makeDir(clientDir) #为每一个客户端建立一个文件夹,用来保存图片 while True: try: data = s.recv(1024).decode() if data == 'end': #图片发送完毕,退出接收图片的循环 break if len(data): #判断是否接收到了数据 fileName,length = data.split('|') #if fileName and length: total_length = int(length) newFile = open(clientDir + '/' + fileName,'wb') s.send(b'ok') get = 0 file = b'' while get < total_length: fileData = s.recv(1024) file = file + fileData get = get + len(fileData) if len(file) == total_length: newFile.write(file[:]) s.send(b'continue') newFile.close() except ConnectionResetError: print('error') s.close() s.send(b'successfully received') #将图片全部接收完毕后,给客户端一个响应 personName = self.recognition.startRecog(clientDir) s.send(personName.encode()) print(personName) def makeDir(self, path): path = path.strip() if not os.path.exists(path): os.mkdir(path) def stop(self): for item in self.clients.values(): item.close() self.sock.close() if __name__ == '__main__': myserver = recogServer() myserver.start() while True: input_str = input('>>>') if input_str.strip() == 'quit': myserver.stop() break print(threading.enumerate())
客户端:
import socket import os class client: def __init__(self): self.fileList = [] # 存图片的bytes数组 self.addr = ('127.0.0.1', 9999) self.sock = socket.socket() self.sock.connect(self.addr) def readFile(self, dir_path): self.nameList = os.listdir(dir_path) for item in self.nameList: file_path = dir_path + item print(file_path) self.fileList.append(self.read(file_path)) def read(self, file_path): file_handle = open(file_path, 'rb') data = file_handle.read() file_handle.close() return data def send_pic(self): pic_num = len(self.nameList) for i in range(pic_num): total_length = len(self.fileList[i]) msg = '{}|{}'.format(self.nameList[i], total_length) self.sock.send(msg.encode()) ok_data = self.sock.recv(1024) if ok_data.decode() == 'ok': current = 0 while current < total_length: send_data = self.fileList[i][current:current+1024] self.sock.send(send_data) current = current + len(send_data) continue_data = self.sock.recv(1024) if continue_data.decode() == 'continue': pass self.sock.send(b'end') over = self.sock.recv(1024) print(over.decode()) name = self.sock.recv(1024) print(name.decode()) if __name__ == '__main__': #path = 'image/' path = input('Input the path:') #例如当前目录下'image/2/' path.strip() myclient = client() myclient.readFile(path) myclient.send_pic()