| | |
| | | self.running = True |
| | | self.recv_buffer = '' |
| | | self.lock = threading.Lock() |
| | | self.consecutive_discards = 0 # 连续丢弃计数器 |
| | | |
| | | # 创建接收线程 |
| | | self.recv_thread = threading.Thread(target=self._recv_loop) |
| | |
| | | readable, _, _ = select.select([self.sock], [], [], 1.0) |
| | | |
| | | if readable: |
| | | data = self.sock.recv(4096) |
| | | # 接收缓冲区大小: 建议至少是最大包长度的2倍,避免频繁recv调用 |
| | | # 最大包 = 4(header) + 8192(payload) = 8196 字节 |
| | | # 使用32768可以容纳3-4个完整包,提高效率 |
| | | data = self.sock.recv(32768) |
| | | |
| | | if not data: |
| | | # 连接断开 |
| | |
| | | print('[Connection] Error: %s' % str(e)) |
| | | break |
| | | |
| | | # 检查是否因大量无效包需要关闭 |
| | | if self.consecutive_discards > 1000: |
| | | print('[Connection] Too many invalid packets, closing connection %d' % self.cid) |
| | | |
| | | self.close() |
| | | |
| | | def _try_parse_packet(self): |
| | |
| | | # PacketHeader: FF CC (2字节) + Length (2字节) = 4字节 |
| | | PACKET_HEADER_SIZE = 4 |
| | | PACKET_HEADER_MC = 0xCCFF |
| | | MAX_PACKET_LEN = 2048 |
| | | MAX_PACKET_LEN = 8192 |
| | | |
| | | if len(self.recv_buffer) < PACKET_HEADER_SIZE: |
| | | return False |
| | |
| | | # 检查 MagicCode (FF CC) |
| | | magic_code = struct.unpack('<H', self.recv_buffer[0:2])[0] |
| | | if magic_code != PACKET_HEADER_MC: |
| | | # 丢弃第一个字节,继续尝试 |
| | | self.consecutive_discards += 1 |
| | | if self.consecutive_discards > 1000: |
| | | packet_logger.log_text('Too many invalid packets, closing connection', 'ERROR') |
| | | return False |
| | | packet_logger.log_text('Invalid magic code: 0x%04X, discard byte (count: %d)' % (magic_code, self.consecutive_discards), 'WARN') |
| | | self.recv_buffer = self.recv_buffer[1:] |
| | | # 整个缓冲区数据无效,清空等待新数据 |
| | | packet_logger.log_text('Invalid magic code: 0x%04X, clear buffer data: %s' % (magic_code, self.recv_buffer), 'WARN') |
| | | self.recv_buffer = '' |
| | | return False |
| | | |
| | | # 读取包长度(不包含PacketHeader本身) |
| | |
| | | |
| | | # 检查包长度是否合理 |
| | | if packet_len > MAX_PACKET_LEN: |
| | | self.consecutive_discards += 1 |
| | | packet_logger.log_text('Packet length %d exceeds max %d, discard byte (count: %d)' % (packet_len, MAX_PACKET_LEN, self.consecutive_discards), 'WARN') |
| | | self.recv_buffer = self.recv_buffer[1:] |
| | | # 整个缓冲区数据无效,清空等待新数据 |
| | | packet_logger.log_text('Packet length %d exceeds max %d, clear buffer. Buffer data: %s' % (packet_len, MAX_PACKET_LEN, self.recv_buffer), 'WARN') |
| | | self.recv_buffer = '' |
| | | return False |
| | | |
| | | # 计算总长度(包含PacketHeader) |
| | |
| | | # 提取协议数据(跳过4字节PacketHeader,只传Cmd/SubCmd及之后的数据) |
| | | packet_data = self.recv_buffer[PACKET_HEADER_SIZE:total_len] |
| | | self.recv_buffer = self.recv_buffer[total_len:] |
| | | |
| | | # 重置丢弃计数器 |
| | | self.consecutive_discards = 0 |
| | | |
| | | # 交给包处理器处理 |
| | | self.packet_processor.add_packet(self.cid, packet_data) |