You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
import socket
|
|
import threading
|
|
from typing import Dict, Callable
|
|
from protocol import Protocol
|
|
|
|
|
|
class TCPClient:
|
|
def __init__(self, host, port):
|
|
self.host = host
|
|
self.port = port
|
|
self.socket = None
|
|
self.connected = False
|
|
self.callbacks: Dict[int, Callable] = {}
|
|
self.receive_thread = None
|
|
self.packet_id = 0
|
|
self.debug_callback = None
|
|
|
|
def connect(self):
|
|
try:
|
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
print(f"host={self.host},port={self.port}\n")
|
|
self.socket.connect((self.host, self.port))
|
|
self.connected = True
|
|
self._start_receive_thread()
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
def disconnect(self):
|
|
self.connected = False
|
|
if self.socket:
|
|
self.socket.close()
|
|
self.socket = None
|
|
|
|
def register_callback(self, cmd, callback):
|
|
self.callbacks[cmd] = callback
|
|
print(f"注册回调: cmd=0x{cmd:02x}, callback={callback.__name__}")
|
|
|
|
def send_packet(self, cmd, data=b''):
|
|
if not self.connected:
|
|
return False
|
|
try:
|
|
packet = Protocol.build_packet(cmd, data)
|
|
|
|
# 记录发送消息(如果有调试回调)
|
|
if self.debug_callback:
|
|
self.debug_callback(cmd, data)
|
|
|
|
self.socket.send(packet)
|
|
return True
|
|
except Exception:
|
|
self.connected = False
|
|
return False
|
|
|
|
def _start_receive_thread(self):
|
|
self.receive_thread = threading.Thread(target=self._receive_loop, daemon=True)
|
|
self.receive_thread.start()
|
|
|
|
def _receive_loop(self):
|
|
#buffer = b''
|
|
while self.connected:
|
|
try:
|
|
data = self.socket.recv(4096)
|
|
if not data:
|
|
break
|
|
self._process_buffer(data)
|
|
except Exception:
|
|
break
|
|
|
|
def _process_buffer(self, buffer):
|
|
while True:
|
|
result = Protocol.parse_packet(buffer)
|
|
if not result:
|
|
break
|
|
header, body = result
|
|
packet_length = len(buffer)
|
|
|
|
if header.cmd in self.callbacks:
|
|
print(f"调用回调: cmd=0x{header.cmd:02x}")
|
|
self.callbacks[header.cmd](header, body)
|
|
else:
|
|
print(f"未找到回调: cmd=0x{header.cmd:02x}")
|
|
buffer = buffer[packet_length:]
|
|
|
|
packet_length = len(buffer) |