import socket import threading import queue import random import struct import time import math from datetime import datetime # 全局配置 HOST = 'localhost' PORT = 10 BUFFER_SIZE = 32768 FRAME_HEADER = b'####' # 长江入海口位置 (中心点) YANGTZE_ESTUARY_LAT = 31.23 YANGTZE_ESTUARY_LON = 121.47 RANGE_NM = 5 # 5海里范围 # 预生成10艘船的MMSI SHIP_MMSIS = [random.randint(200000000, 299999999) for _ in range(10)] # 报文类型定义 MSG_TYPE_DEBUG = 0 MSG_TYPE_LVDS = 1 MSG_TYPE_CAN = 2 MSG_TYPE_AD9361 = 3 MSG_TYPE_WAVE_CTRL = 4 MSG_TYPE_TEST_PARAM = 5 MSG_TYPE_TEST_WAVE = 6 MSG_TYPE_GPS = 7 MSG_TYPE_STATUS = 8 MSG_TYPE_VDES_CTRL = 9 MSG_TYPE_VDES_UPLOAD = 10 MSG_TYPE_COLLECT = 11 MSG_TYPE_DEMOD = 12 MSG_TYPE_NOTIFY = 13 # 解调器类型 DEMOD_VDES = 0 # VDES解调器 (0-3) DEMOD_AIS = 4 # AIS解调器 (4-5) # 通信状态定义 (Annex 2 Table 18) COMM_STATES = [ {"sync_state": 0, "slot_timeout": 0, "sub_message": 0}, {"sync_state": 1, "slot_timeout": 1, "sub_message": 1}, {"sync_state": 2, "slot_timeout": 2, "sub_message": 2}, {"sync_state": 3, "slot_timeout": 3, "sub_message": 3} ] class VDESTCPServer: def __init__(self): self.send_queue = queue.Queue() self.running = True self.device_state = { "cpu0": 50, "cpu1": 50, "version": 0x01020304, "uptime": int(time.time()), "gps_status": 1, "pps_lock": 1, "ad9361_status": 2 } self.gps_params = self.generate_gps_data() def start(self): # server_thread = threading.Thread(target=self.run_server) # server_thread.daemon = True # server_thread.start() # send_thread = threading.Thread(target=self.send_data_thread) # send_thread.daemon = True # send_thread.start() # server_thread.join() # send_thread.join() print(11111111111) print(self.build_gps_message()) def run_server(self): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"VDES TCP Server listening on {HOST}:{PORT}") while self.running: conn, addr = s.accept() print(f"Connected by {addr}") client_thread = threading.Thread(target=self.handle_client, args=(conn,)) client_thread.daemon = True client_thread.start() def handle_client(self, conn): with conn: while self.running: try: data = conn.recv(BUFFER_SIZE) if not data: break # 解析报文 if len(data) < 12: print("Invalid packet size") continue header = data[:4] if header != FRAME_HEADER: print("Invalid frame header") continue msg_type = struct.unpack('>I', data[4:8])[0] msg_len = struct.unpack('>I', data[8:12])[0] msg_content = data[12:12+msg_len] if msg_len > 0 else b'' print(f"Received message type: {msg_type}, length: {msg_len}") # 处理报文并准备响应 response = self.process_message(msg_type, msg_content) if response: self.send_queue.put(response) except Exception as e: print(f"Error handling client: {e}") break def process_message(self, msg_type, content): """处理接收到的报文并返回响应""" response = None if msg_type == MSG_TYPE_DEBUG: # 调试指令报文 if len(content) >= 1: cmd_type = content[0] print(f"Received debug command: {cmd_type}") # 简单响应通知报文 response = self.build_notify_message(0, "Debug command processed") elif msg_type == MSG_TYPE_AD9361: # AD9361参数控制 print("Received AD9361 control params") response = self.build_notify_message(0, "AD9361 params updated") elif msg_type == MSG_TYPE_TEST_PARAM: # 发送测试参数控制 if len(content) >= 9: test_type, test_count, test_interval = struct.unpack('>BII', content[:9]) print(f"Test params: type={test_type}, count={test_count}, interval={test_interval}ms") response = self.build_notify_message(0, "Test params accepted") elif msg_type == MSG_TYPE_VDES_CTRL: # VDES协议参数控制 print("Received VDES control params") response = self.build_notify_message(0, "VDES params updated") elif msg_type == MSG_TYPE_VDES_UPLOAD: # VDES上注数据 if len(content) >= 1: data_type = content[0] print(f"VDES upload data type: {data_type}") response = self.build_notify_message(0, "Data upload accepted") return response def send_data_thread(self): """发送线程,定期发送GPS和解调数据报文""" while self.running: try: # 发送GPS数据 (每秒一次) self.gps_params = self.generate_gps_data() gps_msg = self.build_gps_message() self.send_queue.put(gps_msg) # 发送解调数据 (随机间隔) if random.random() > 0.7: demod_msg = self.build_demod_message() self.send_queue.put(demod_msg) # 发送状态监控数据 (每秒一次) status_msg = self.build_status_message() self.send_queue.put(status_msg) # 发送队列中的响应报文 while not self.send_queue.empty(): msg = self.send_queue.get() # 在实际服务器中,这里应该发送给所有连接的客户端 # 本示例中仅打印发送信息 print(f"Sending message type: {struct.unpack('>I', msg[4:8])[0]}, " f"length: {struct.unpack('>I', msg[8:12])[0]}") time.sleep(1) except Exception as e: print(f"Error in send thread: {e}") def build_packet(self, msg_type, content): """构建完整TCP报文""" header = FRAME_HEADER type_field = struct.pack('>I', msg_type) length_field = struct.pack('>I', len(content)) return header + type_field + length_field + content def build_gps_message(self): """构建GPS解析数据报文 (类型7)""" content = struct.pack('>QiiihhhBBBBBB', self.gps_params["utc_time"], self.gps_params["longitude"], self.gps_params["latitude"], self.gps_params["altitude"], self.gps_params["used_sats"], self.gps_params["gps_sats"], self.gps_params["beidou_sats"], self.gps_params["gps_status"], self.gps_params["fix_mode"], self.gps_params["hdop"], self.gps_params["speed"], self.gps_params["course"]) return self.build_packet(MSG_TYPE_GPS, content) def build_demod_message(self): """构建VDES解调数据报文 (类型12)""" demod_id = random.randint(0, 5) comm_state = random.choice(COMM_STATES) if demod_id <= DEMOD_VDES + 3: # VDES解调器 (0-3) # 根据M.2092-1 Annex5 3.10生成消息 msg_data = self.generate_vdes_message() else: # AIS解调器 (4-5) # 根据M.1371-5 Annex8 3.1生成Message1 msg_data = self.generate_ais_message1() # 构建通信状态字段 comm_state_field = struct.pack('>BBH', (comm_state["sync_state"] << 6) | (comm_state["slot_timeout"] << 3), comm_state["sub_message"] >> 8, comm_state["sub_message"] & 0xFF) # 构建完整报文 content = struct.pack('>BBHH', 12, demod_id, random.randint(0, 65535), random.randint(0, 65535)) content += struct.pack('>H', random.randint(-12800, 12700)) # 信噪比 content += comm_state_field content += msg_data return self.build_packet(MSG_TYPE_DEMOD, content) def build_status_message(self): """构建地检状态监控报文 (类型8)""" # 更新设备状态 self.device_state["cpu0"] = random.randint(40, 60) self.device_state["cpu1"] = random.randint(40, 60) self.device_state["uptime"] = int(time.time()) # 构建报文内容 (简化版) content = struct.pack('>BBIIBBBB', self.device_state["cpu0"], self.device_state["cpu1"], self.device_state["version"], self.device_state["uptime"], self.device_state["gps_status"], self.device_state["pps_lock"], self.device_state["ad9361_status"], 0) # 校准因子占位 return self.build_packet(MSG_TYPE_STATUS, content) def build_notify_message(self, msg_type, text): """构建消息通知报文 (类型13)""" text_bytes = text.encode('utf-8') content = struct.pack('>B', msg_type) + text_bytes return self.build_packet(MSG_TYPE_NOTIFY, content) def generate_gps_data(self): """生成GPS数据 (长江入海口5海里范围内)""" # 在中心点附近5海里范围内生成随机位置 lat, lon = self.generate_random_position() return { "utc_time": int(time.time()), "longitude": int(lon * 10000000), "latitude": int(lat * 10000000), "altitude": random.randint(-50, 100), "used_sats": random.randint(5, 12), "gps_sats": random.randint(3, 8), "beidou_sats": random.randint(3, 8), "gps_status": random.randint(0, 4), "fix_mode": random.randint(1, 3), "hdop": random.randint(10, 100), "speed": random.randint(0, 2000), # 0.01节单位 "course": random.randint(0, 35900) # 0.01度单位 } def generate_random_position(self): """在长江入海口5海里范围内生成随机位置""" # 1海里 ≈ 0.0166667度 (赤道附近) offset_lat = (random.random() - 0.5) * RANGE_NM * 0.0166667 offset_lon = (random.random() - 0.5) * RANGE_NM * 0.0166667 lat = YANGTZE_ESTUARY_LAT + offset_lat lon = YANGTZE_ESTUARY_LON + offset_lon return lat, lon def generate_vdes_message(self): """生成VDES消息 (M.2092-1 Annex5 3.10)""" # 随机选择一种消息类型 (简化实现) msg_types = [0, 1, 2, 3, 4, 5] msg_type = random.choice(msg_types) # 构建基本消息结构 msg = struct.pack('>B', msg_type) # 添加随机内容 if msg_type == 0: # Paging msg += struct.pack('>I', random.randint(100000000, 999999999)) elif msg_type == 1: # Resource request msg += struct.pack('>IB', random.randint(100000000, 999999999), random.randint(0, 255)) return msg def generate_ais_message1(self): """生成AIS Message1位置报告 (M.1371-5 Annex8 3.1)""" # 随机位置 lat, lon = self.generate_random_position() # 转换为AIS格式 lat_ais = int((lat + 90) * 60000) lon_ais = int((lon + 180) * 60000) # 随机选择一艘船 mmsi = random.choice(SHIP_MMSIS) # 随机通信状态 comm_state = random.choice(COMM_STATES) comm_state_field = ( (comm_state["sync_state"] << 17) | (comm_state["slot_timeout"] << 14) | comm_state["sub_message"] ) # 构建Message1 (168位/21字节) msg = struct.pack('>I', (1 << 26) | (random.randint(0, 3) << 24) | (mmsi >> 6)) msg += struct.pack('>I', ((mmsi & 0x3F) << 26) | (random.randint(0, 15) << 22)) msg += struct.pack('>I', (random.randint(0, 255) << 24) | (random.randint(0, 1023) << 14)) msg += struct.pack('>I', (random.randint(0, 1) << 31) | (lon_ais & 0xFFFFFFF)) msg += struct.pack('>I', (lat_ais << 4) | (random.randint(0, 4095) >> 8)) msg += struct.pack('>I', ((random.randint(0, 4095) & 0xFF) << 24) | (random.randint(0, 3599) << 12)) msg += struct.pack('>I', (random.randint(0, 511) << 23) | (random.randint(0, 63) << 17) | (comm_state_field & 0x1FFFF)) return msg if __name__ == "__main__": server = VDESTCPServer() server.start()