class cliSock: def __init__(self, IP, port): self.__IP = IP self.__port = port self.__add = (self.__IP, self.__port) self.__sock = None self.__isBusy = False self.__encryption = Encrypt() self.lock = threading.Lock() self.image = None self.text = None def setConnect(self): print('Waiting for connection...') while True: try: self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__sock.connect(self.__add) self.__sock.send('BEATS'.encode()) conn_bytes = self.__sock.recv(1024) conn = conn_bytes.decode() if conn == 'BEATS': print('Connect to ', self.__IP, ':', self.__port) return True else: # 没有正确收到心跳回应 return False except: print('Waiting for connection...') pass def disConnect(self): self.__sock.send('CLOSE'.encode()) self.__sock.shutdown(2) print("Connection interrupted!") def monitor(self, textShow, imgShow): th_mon = threading.Thread(target=cliSock.__monitor, args=(self, textShow, imgShow)) try: th_mon.start() print('Start monitor') except: pass def sendText(self, text): text = self.__encryption.TextEncrypt(text) th_sendText = threading.Thread(target=cliSock.__sendText, args=(self, text)) try: th_sendText.start() print('Start send text') except: pass def sendImg(self, img): ''' input: img: 为PIL.Image 类型 不是的话需要提前转化!!! ''' img = self.__encryption.ImageEncrypt(img) th_sendImg = threading.Thread(target=cliSock.__sendImg, args=(self, img)) try: th_sendImg.start() print('Start send Image') except: pass def __monitor(self, textShow, imgShow): # beats = 0 心跳计数 while True: self.lock.acquire() try: self.__sock.settimeout(3) conn_bytes = self.__sock.recv(1024) conn = conn_bytes.decode() if conn[0] == 'H': self.__sock.settimeout(None) if conn.split('-')[1] == 'TEXT': self.__getText(conn, textShow) elif conn.split('-')[1] == 'IMG': self.__getImg(conn, imgShow) else: print('BAD HEADER') elif conn == 'CLOSE': self.__sock.shutdown(2) self.__sock.close() print('Connect interrupted!') break else: print('Error message!') break except: # self.__sock.settimeout(None) # ??? # beats += 1 # if beats == 3: # 进行心跳 # self.__sock.send('BEATS'.encode()) # try: # conn_bytes = self.__sock.recv(1024) # conn = conn_bytes.decode() # if conn == 'BEATS': # print('BEATS Success!') # except: # print('Heart Beats Error! \n Loss Connection!') # break # beats = 0 pass self.__sock.settimeout(None) self.lock.release() time.sleep(3) def __getText(self, head, textShow): ''' input: textShow 传入参数为u一个tuple (head, conn) ''' self.__sock.send(head.encode()) length = int(head.split('-')[-1]) while True: conn_bytes = self.__sock.recv(length) if len(conn_bytes) == length: self.__sock.send(str(length).encode()) textShow((head, conn_bytes)) break else: print('ERROR: get wrong text') def __getImg(self, head, imgShow): ''' input: imgShow 传入参数为一个tuple (head, conn) ''' self.__sock.send(head.encode()) length = int(head.split('-')[-1]) while True: conn_bytes = self.__sock.recv(length) # conn = conn_bytes.decode() if len(conn_bytes) == length: self.__sock.send(str(length).encode()) imgShow((head, conn_bytes)) break else: print('ERROR: get wrong image') def __sendText(self, text): self.lock.acquire() length = len(text.encode()) head = 'H-TEXT-' + str(length) self.__sock.send(head.encode()) try: head_bytes = self.__sock.recv(1024) if head_bytes.decode() == head: self.__sock.send(text.encode()) length_bytes = self.__sock.recv(1024) if length_bytes.decode() == str(length): print('Server get message successfully') else: print('ERROR : Return Wrong Length!') else: print('ERROR : Return Wrong header!') except: print('ERROR : Server does n\'t get the Header!') self.lock.release() def __sendImg(self, img): self.lock.acquire() mode = img.mode # str img_bytes = img.tobytes() # bytes length = len(img_bytes) width, height = img.size head = 'H-IMG-' + mode + '-' + str(width) + '-' + str( height) + '-' + str(length) self.__sock.send(head.encode()) try: head_bytes = self.__sock.recv(1024) if head_bytes.decode() == head: self.__sock.send(img_bytes) length_bytes = self.__sock.recv(1024) if length_bytes.decode() == str(length): print('Server get Image successfully!') else: print('ERROR : Return Wrong Length') else: print('ERROR : Return Wrong Header!') except: print('ERROR : Server does n\'t get the Header!') self.lock.release()
class serSock: def __init__(self, IP, port): self.__IP = IP self.__port = port self.__add = (self.__IP, self.__port) self.__encryption = Encrypt() self.image = None self.text = None self.__s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__s.bind((self.__IP, self.__port)) self.__s.listen(2) self.__cli = None self.lock = threading.Lock() def setConnect(self): print('Waiting for connection...') while True: self.__cli, add = self.__s.accept() try: conn_bytes = self.__cli.recv(1024) if conn_bytes.decode() == 'BEATS': self.__cli.send('BEATS'.encode()) print('connect to', add[0], ':', add[1]) return True except: print('Waiting for connection...') pass def disConnect(self): self.__cli.send('CLOSE'.encode()) self.__cli.shutdown(2) self.__cli.close() self.__s.shutdown(2) self.__s.close() print("Connection interrupted!") def monitor(self, textShow, imgShow): # textShow 为文字展示函数 在这里传递 print th_mon = threading.Thread(target=serSock.__monitor, args=(self, textShow, imgShow)) try: # 可能在lock时 使用者手贱点好几次,会发生重复启动报错 th_mon.start() print('Monitor thread start!') except: pass def sendText(self, text): text = self.__encryption.TextEncrypt(text) th_sendText = threading.Thread(target=serSock.__sendText, args=(self, text)) try: th_sendText.start() print('Start send text') except: pass def sendImg(self, img): ''' input: img: 为PIL.Image 类型 不是的话需要提前转化!!! ''' img = self.__encryption.ImageEncrypt(img) th_sendImg = threading.Thread(target=serSock.__sendImg, args=(self, img)) try: th_sendImg.start() print('Start send Image') except: pass def __monitor(self, textShow, imgShow): while True: self.lock.acquire() try: self.__cli.settimeout(3) # 防止持续阻塞 conn_bytes = self.__cli.recv(1024) conn = conn_bytes.decode() if conn[0] == 'H': self.__cli.settimeout(None) # 收到 header 恢复阻塞 if conn.split('-')[1] == 'TEXT': self.__getText(conn, textShow) elif conn.split('-')[1] == 'IMG': self.__getImg(conn, imgShow) else: print('BAD HEADER!') elif conn == 'BEATS': self.__cli.send('BEATS'.encode()) print('Get BEATS') elif conn == 'CLOSE': self.__cli.shutdown(2) self.__cli.close() self.__s.shutdown(2) self.__s.close() print('Connect interrupted!') break else: print('Error message!') break except: pass self.__cli.settimeout(None) self.lock.release() time.sleep(3) def __getText(self, head, textShow): ''' input: textShow 传入参数为u一个tuple (head, conn) ''' self.__cli.send(head.encode()) length = int(head.split('-')[-1]) while True: conn_bytes = self.__cli.recv(length) # conn = conn_bytes.decode() if len(conn_bytes) == length: self.__cli.send(str(length).encode()) textShow((head, conn_bytes)) break else: print('ERROR: get wrong text') def __getImg(self, head, imgShow): ''' input: imgShow 传入参数为一个tuple (head, conn) ''' self.__cli.send(head.encode()) length = int(head.split('-')[-1]) while True: conn_bytes = self.__cli.recv(length) if len(conn_bytes) == length: self.__cli.send(str(length).encode()) imgShow((head, conn_bytes)) break else: print('ERROR: get wrong image') def __sendText(self, text): self.lock.acquire() length = len(text.encode()) head = 'H-TEXT-' + str(length) self.__cli.send(head.encode()) self.__cli.settimeout(None) try: head_bytes = self.__cli.recv(1024) if head_bytes.decode() == head: self.__cli.send(text.encode()) length_bytes = self.__cli.recv(1024) if length_bytes.decode() == str(length): print('Client get message successfully') else: print('ERROR : Return Wrong Length!') else: print('ERROR : Return Wrong header!') except: print('ERROR : Client does n\'t get the Header!') self.lock.release() def __sendImg(self, img): self.lock.acquire() mode = img.mode # str img_bytes = img.tobytes() # bytes length = len(img_bytes) width, height = img.size head = 'H-IMG-' + mode + '-' + str(width) + '-' + str( height) + '-' + str(length) self.__cli.send(head.encode()) try: head_bytes = self.__cli.recv(1024) if head_bytes.decode() == head: self.__cli.send(img_bytes) length_bytes = self.__cli.recv(1024) if length_bytes.decode() == str(length): print('Client get Image successfully!') else: print('ERROR : Return Wrong Length') else: print('ERROR : Return Wrong Header!') except: print('ERROR : Client does n\'t get the Header!') self.lock.release()
class Sock: def __init__(self, IP, port, retryTimes=3, timeout=10): self.__IP = IP self.__port = port self.__add = (self.__IP, self.__port) self.__sock = None self.__isBusy = False self.__errLimit = retryTimes self.__timeout = timeout self.__encryption = Encrypt() self.image = None self.text = None def setConnect(self): # 随子类方法变动 # 留给子类定义 pass def __monitor(self): while True: # 开始监听 if self.__isBusy == True: # 如果有任务 等待 time.sleep(30) continue self.__isBusy = True # 设置监听 try: conn = self.__sock.recv(1024) head = conn.decode() # 假设流程正常 conn 应该为一个 header if head[0] != 'H': # header 错误 pass else: kind = head.split('-')[1] if kind == 'TEXT': length = conn.split('-')[2] self.__sock.send(conn) # 回发 conn 确认 while True: try: conn = self.__sock.recv(length) text = conn.decode() if len(text) == length: self.__sock.send(str(length).encode()) self.text = text else: # 未接到正确信息 pass except: # 未接到信息 pass elif kind == 'IMAGE': mode = head.split('-')[1] size = (int(head.split('-')[2]), int(head.split('-')[3])) length = head.split('-')[-1] self.__sock.send(conn) # 回发 conn 确认 while True: try: conn = self.__sock.recv(length) image = conn.decode() if len(image) == length: self.__sock.send(str(length)) self.image = Image.frombytes( mode, size, image) else: # 未收到正确信息 pass except: pass else: # header 错误 pass self.__isBusy = False time.sleep(30) except: # 对方未发送 进行一次心跳 self.__heartBeats() self.__isBusy = False time.sleep(30) pass def disConnect(self): if self.__isBusy == False: self.__sock.shutdown(2) self.__sock.close() else: # 正在工作 无法关闭 return False def __heartBeats(self): ''' return : True : 表示连接正常 False : 表示断开 ''' beats = "BEATS".encode() res = self.__sendAndConf(beats, beats) return res def sendText(self, text): if self.__isBusy == True: return False self.__isBusy = True text = self.__encryption.TextEncrypt(text) length = str(len(text)) head = 'H-TEXT-' + length if self.__sendHead(head.encode()) == False: return False if self.__sendTextB(text.encode(), length.encode()) == False: return False self.__isBusy = False return True def sendImage(self, path): ''' input : path 图片路径 return : True : 发送成功 False : 发送失败 ''' if self.__isBusy == True: # 正在接收数据 # 增加报错 return False self.__isBusy = True image = self.__getImage(path) if image == None: # path error return False mode = image.mode image_bytes = image.tobytes() size = image.size length = len(image_bytes) head = 'H-IMG-' + mode + '-' + str(size[0]) + '-' + str( size[1]) + '-' + str(length) if self.__sendHead(head.encode()) == False: return False if self.__sendImageB(image_bytes, str(length).encode()) == False: return False self.__isBusy = False return True def __sendHead(self, head): # head : bytes 类型 res = self.__sendAndConf(head, head) return res def __sendImageB(self, image_bytes, length): # image_bytes , length : bytes 类型 res = self.__sendAndConf(image_bytes, length) return res def __sendTextB(self, text_bytes, length): # text_bytes , length : bytes 类型 res = self.__sendAndConf(text_bytes, length) return res def __sendAndConf(self, toSend, toConf): ''' input : toSend : bytes 类型 toConf : bytes 类型 return : True : 正确运行 False : 错误运行 ''' errTimes = 0 while True: try: self.__sock.send(toSend) while True: try: conn = self.__sock.recv(1024) if conn == toConf: return True else: errTimes += 1 if errTimes == self.__errLimit: # 报错 回复信息不正确 return False except: errTimes += 1 if errTimes == self.__errLimit: # 报错 无法接收 return False time.sleep(3) except: errTimes += 1 if errTimes == self.__errLimit: # 报错 无法发送 return False time.sleep(3) def getImage(self, path): ''' input : path : 图片地址 return : image : PIL.Image 类型 ''' try: image = Image.open(path) return self.__encryption.ImageEncrypt(image) except: return None @property def IP(self): return self.__IP @property def port(self): return self.__port @property def add(self): return self.__add @property def isBusy(self): return self.__isBusy @property def errLimit(self): return self.__errLimit @property def timeout(self): return self.__timeout