def _on_recv_header(self, data): (body_size, ) = struct.unpack('!I', data) if body_size > self.TCP_MAX_PACKET_SIZE: log.error('tcp_asnyc_client_body_size_overflow|id=%s,size=%u', self._id, body_size) self._close() return self._stream.read_bytes(body_size, self._on_recv_body)
def _on_client_close(self, client): # log.debug('tcp_server_client_close|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.debug('tcp_server_client_close|id=%s,remote=%s', byteshex(client.id), client.remote_address) if client.id not in self._clients: # log.error('tcp_server_close_conn_not_found|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.error('tcp_server_close_conn_not_found|id=%s,remote=%s', byteshex(client.id), client.remote_address) return self._handle_task(client, GTCP_CMD_DISCONNECT, b'') del self._clients[client.id]
def _on_recv_header(self, data): if len(data) != self.HEADER_SIZE: # log.error('tcp_conn_header_size_error|remote=%s,header=%s', self._remote_address, data.encode('hex')) log.error('tcp_conn_header_size_error|remote=%s,header=%s', self._remote_address, byteshex(data)) self._stream.close() return (body_size, ) = struct.unpack('%sI' % self._endian, data) if body_size >= self._config.TCP_MAX_PACKET_SIZE: log.error('tcp_conn_body_size_overflow|remote=%s,size=%u', self._remote_address, body_size) self._stream.close() return self._stream.read_bytes(body_size, self._on_recv_body)
def _on_client_connect(self, stream, address): client = GTcpConnection(stream, address, self._config, self._on_client_packet, self._on_client_close, endian="!") if client.id in self._clients: # log.error('tcp_server_dup_client|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.error('tcp_server_dup_client|id=%s,remote=%s', client.id, client.remote_address) self._clients[client.id] = client self._handle_task(client, GTCP_CMD_CONNECT, b'') # log.debug('tcp_server_client_connect|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.debug('tcp_server_client_connect|id=%s,remote=%s', client.id, client.remote_address)
def run(self): random.seed() self.on_init() from sakura.gtcpclient import GTcpClient log.debug('tcp_worker_start|id=%d', self._id) self._client = GTcpClient(self._config.WORK_ENDPOINT['address'], self._config.WORK_ENDPOINT['port'], 0) while True: try: request = self._client.receive() if request is None: log.warn( 'tcp worker lost_connection|client_id=%s,client=%s', byteshex(self._id), self._client._address) self._client.close() elif len(request) < GTCP_HEADER_SIZE: log.error( 'tcp_worker_request_packet_error|client_id=%s,client=%s,request=%s', byteshex(self._id), self._client._address, byteshex(request)) self._client.close() else: request_cmd = request[:GTCP_CMD_SIZE] request_client = TcpEndpoint( request[GTCP_CMD_SIZE:GTCP_HEADER_SIZE]) reply_body = None if request_cmd == GTCP_CMD_RELAY: request_body = request[GTCP_HEADER_SIZE:] reply_body = self.on_packet(request_client, request_body) elif request_cmd == GTCP_CMD_CONNECT: reply_body = self.on_client_connect(request_client) elif request_cmd == GTCP_CMD_DISCONNECT: self.on_client_disconnect(request_client) if reply_body is None: self._client.send(GTCP_CMD_NONE + request_client.client_id) else: self._client.send(GTCP_CMD_RELAY + request_client.client_id + reply_body) except Exception as ex: log.exception('tcp_worker_exception|id=%u,exception=%s', self._id, ex, exc_info=True) self._client.close()
def _on_worker_packet(self, worker, data): client = worker.running_task.client packet_size = len(data) if packet_size < GTCP_HEADER_SIZE: # log.error('tcp_worker_reply_error|client_id=%s,client=%s,reply=%s', client.id.encode('hex'), client.remote_address, data.encode('hex')) log.error('tcp_worker_reply_error|client_id=%s,client=%s,reply=%s', byteshex(client.id), client.remote_address, byteshex(data)) worker.running_task.client.close() return reply_cmd = data[:1] if reply_cmd == GTCP_CMD_RELAY or reply_cmd == GTCP_CMD_NOTIFY: reply_client = data[GTCP_CMD_SIZE:GTCP_HEADER_SIZE] reply_data = data[GTCP_HEADER_SIZE:] if reply_client in self._clients: self._clients[reply_client].send_packet(reply_data) else: # log.error('tcp_reply_client_not_found|client_id=%s,reply=%s', reply_client.encode('hex'), reply_data.encode('hex')) log.error('tcp_reply_client_not_found|client_id=%s,reply=%s', byteshex(reply_client), byteshex(reply_data)) worker.running_task.client.close() if reply_cmd != GTCP_CMD_NOTIFY: self._on_worker_idle(worker)