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)
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()
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')