Exemplo n.º 1
0
    def run(self):
        """线程主函数

        循环运行,接受新的客户端的连接。
        """
        log.info('server thread: start, port: %d' % self.port)
        try:
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server.bind(('0.0.0.0', self.port))
            server.listen(1)
            server.settimeout(3)  # timeout: 3s
            while self.running:
                try:
                    conn, address = server.accept()
                    conn.settimeout(3)
                    self.got_client_cb(conn, address)
                    log.debug('new client from: %s' % str(address))
                except socket.timeout:
                    pass
            server.close()
            log.info('server thread: bye')
        except Exception as e:
            log.error('server thread error: %s' % e)
            self.running = False
    def receive_data(self):
        """建立连接并循环接收数据

        在超时时重连,在出错时返回。
        """
        client = self.connect()
        log.info('client thread: connected')
        timeout_count = 0
        while self.running:
            try:
                # 接收数据
                data = client.recv(BUFFER_SIZE)
                # 连接失败的处理
                if len(data) == 0:
                    raise RuntimeError('socket connection broken')
                # 收到数据后的处理
                self.rcv_count += 1
                log.debug('rcv %d bytes. id: %d' % (len(data), self.rcv_count))
                self.got_data_cb(data, self.rcv_count)
                timeout_count = 0
            except socket.timeout:
                # 超时处理,超时5次时主动重连
                # 超时时间短是为了在需要时能快速退出
                timeout_count += 1
                if timeout_count >= 5:
                    timeout_count = 0
                    client = self.reconnect(client)
                    log.debug('client timeout, reconnect')
        try:
            client.close()
        except socket.error:
            pass
        except Exception as e:
            log.error('client exception when close: %s' % e)
Exemplo n.º 3
0
    def receive_data(self):
        """接收一个数据包

        并追加到 self.buffer 中。
        """
        data = self.client.recv(BUFFER_SIZE)
        if len(data) == 0:
            raise RuntimeError('socket connection broken')
        self.buffer.extend(data)
        log.debug('control rcv %d bytes.' % len(data))
    def update(self, timestamp, status):
        """线程主函数

        Args:
            timestamp: 时间戳
            status: PCB板发来的心跳包
        """
        log.debug('heartbeat from %s: %s at %s' %
                  (self.device_id, status, timestamp))
        self.timestamp_last_active = timestamp
        self.status = status
    def on_recv_heartbeat(self, sender_id, heartbeat, timestamp):
        """收到一条完整心跳包时的处理函数

        由各 sender_thread 调用

        Args:
            sender_id: 收到心跳包的线程 ID
            heartbeat (bytes): 心跳包
            timestamp: 收到心跳包的时间
        """
        log.debug('pcb manager: from sender %d: %s' % (sender_id, heartbeat))
        self.lock.acquire()
        try:
            self.parse_heartbeat(heartbeat, timestamp)
        except Exception as e:
            log.error('pcb manager: when parse from sender %d: %s' %
                      (sender_id, e))
        self.lock.release()
Exemplo n.º 6
0
    def run(self):
        """线程主函数

        循环运行,不断把 self.data_queue 中的数据包分发给各 SenderThread
        """
        log.info('dispatcher thread: start')
        while self.running:
            try:
                data, rcv_count = self.data_queue.get(timeout=1)
                try:
                    num_clients = self.send_data(data)
                    self.data_queue.task_done()
                    log.debug('send %d bytes to %d clients. id: %d' % (len(data), num_clients, rcv_count))
                except Exception as e:
                    log.error('dispatcher thread error: %s' % e)
            except queue.Empty:
                pass
        self.stop_all_clients()
        log.info('dispatcher thread: bye')