Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
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