skyeyesystem/MiniSAR-Simulator-Py-main/test_client.py
2026-01-29 09:47:15 +08:00

223 lines
6.7 KiB
Python

"""
测试客户端程序
用于测试UDP交互系统
"""
import socket
import struct
import logging
import time
from data_structures import (
ControlPacket, ControlData, WorkMode, WorkInstruction,
CONTROL_RX_PORT, CONTROL_TX_PORT, DATA_TX_PORT
)
class TestClient:
"""测试客户端"""
def __init__(self, server_host: str = '127.0.0.1'):
"""
初始化测试客户端
Args:
server_host: 服务器地址
"""
self.server_host = server_host
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.rx_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.rx_socket.bind(('0.0.0.0', CONTROL_TX_PORT)) # 绑定到随机端口
self.local_port = self.rx_socket.getsockname()[1]
# 配置日志
self.logger = logging.getLogger('TestClient')
self.logger.setLevel(logging.DEBUG)
if not self.logger.handlers:
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
self.logger.addHandler(handler)
self.logger.info(f"Test client initialized on port {self.local_port}")
def send_control_packet(self, work_mode: int, work_instruction: int,
route_number: int = 0, route_count: int = 0) -> bool:
"""
发送控制包
Args:
work_mode: 工作模式
work_instruction: 工作指令
route_number: 航线编号
route_count: 航线个数
Returns:
是否发送成功
"""
try:
# 创建控制数据
control_data = ControlData(
work_mode=work_mode,
work_instruction=work_instruction,
route_number=route_number,
route_count=route_count
)
# 创建控制包
packet = ControlPacket(control_data=control_data)
# 序列化
data = packet.to_bytes()
# Debug logging
self.logger.info(f"DEBUG: Preparing to send packet - Mode: {work_mode}, Instr: {work_instruction}, Route#: {route_number}, Count: {route_count}")
self.logger.info(f"DEBUG: Raw packet data ({len(data)} bytes): {data.hex()}")
# 发送
self.socket.sendto(data, (self.server_host, CONTROL_RX_PORT))
self.logger.info(f"Control packet sent: mode={work_mode}, instruction={work_instruction}")
return True
except Exception as e:
self.logger.error(f"Failed to send control packet: {e}")
return False
def receive_response(self, timeout: float = 2.0) -> bool:
"""
接收响应包
Args:
timeout: 接收超时时间(秒)
Returns:
是否接收成功
"""
try:
self.rx_socket.settimeout(timeout)
data, addr = self.rx_socket.recvfrom(2048)
self.logger.info(f"Response received from {addr} ({len(data)} bytes)")
self.logger.debug(f"Response data (hex): {data.hex()}")
return True
except socket.timeout:
self.logger.warning("Response receive timeout")
return False
except Exception as e:
self.logger.error(f"Failed to receive response: {e}")
return False
def test_connect(self):
"""测试连接指令"""
self.logger.info("=== Testing CONNECT ===")
self.send_control_packet(WorkMode.NORMAL, WorkInstruction.CONNECT)
time.sleep(0.5)
self.receive_response()
def test_disconnect(self):
"""测试断开连接指令"""
self.logger.info("=== Testing DISCONNECT ===")
self.send_control_packet(WorkMode.NORMAL, WorkInstruction.DISCONNECT)
time.sleep(0.5)
self.receive_response()
def test_upload_route(self):
"""测试上传航线指令"""
self.logger.info("=== Testing UPLOAD_ROUTE ===")
self.send_control_packet(
WorkMode.AUTO,
WorkInstruction.UPLOAD_ROUTE,
route_number=0,
route_count=1
)
time.sleep(0.5)
self.receive_response()
def test_start_calc(self):
"""测试开始计算指令"""
self.logger.info("=== Testing START_CALC ===")
self.send_control_packet(WorkMode.AUTO, WorkInstruction.START_CALC)
time.sleep(0.5)
self.receive_response()
def test_manual_boot(self):
"""测试手动开机指令"""
self.logger.info("=== Testing MANUAL_BOOT ===")
self.send_control_packet(WorkMode.AUTO, WorkInstruction.MANUAL_BOOT)
time.sleep(0.5)
self.receive_response()
def test_end_task(self):
"""测试结束当前任务指令"""
self.logger.info("=== Testing END_TASK ===")
self.send_control_packet(WorkMode.AUTO, WorkInstruction.END_TASK)
time.sleep(0.5)
self.receive_response()
def test_end_all_tasks(self):
"""测试结束所有任务指令"""
self.logger.info("=== Testing END_ALL_TASKS ===")
self.send_control_packet(WorkMode.NORMAL, WorkInstruction.END_TASK)
time.sleep(0.5)
self.receive_response()
def run_full_test(self):
"""运行完整测试"""
self.logger.info("Starting full test sequence...")
# 测试连接
self.test_connect()
time.sleep(1)
# 测试上传航线
self.test_upload_route()
time.sleep(1)
# 测试开始计算
self.test_start_calc()
time.sleep(1)
# 测试手动开机
self.test_manual_boot()
time.sleep(1)
# 测试结束任务
self.test_end_task()
time.sleep(1)
# 测试断开连接
self.test_disconnect()
self.logger.info("Full test sequence completed")
def close(self):
"""关闭客户端"""
self.socket.close()
self.rx_socket.close()
self.logger.info("Test client closed")
def main():
"""主函数"""
logging.basicConfig(level=logging.INFO)
# 创建测试客户端
client = TestClient('127.0.0.1')
try:
# 运行完整测试
client.run_full_test()
except KeyboardInterrupt:
logging.info("Test interrupted")
finally:
client.close()
if __name__ == '__main__':
main()