import struct import socket import time from fuadmin import settings class VdesMessagePackaged: """VDES消息打包工具类""" def __init__(self, Message, MMSI): self.message = Message self.MMSI = int(MMSI) self.chunk_size = 32755 self.host = getattr(settings, 'VDES_MONITOR_HOST', 'localhost') self.port = getattr(settings, 'VDES_MONITOR_PORT', 8083) self.buffer_size = getattr(settings, 'VDES_BUFFER_SIZE', 4096) def create_tcp_packet(self, packet_type, content): """创建符合VDES TCP协议的报文""" # 报文帧头 (4字节) header = b'####' # 报文类型 (4字节,大端) type_field = struct.pack('>I', packet_type) # 报文长度 (4字节,大端,内容长度) length = len(content) length_field = struct.pack('>I', length) # 构建完整报文 packet = header + type_field + length_field + content return packet #长消息起始片段 def long_message_start_frame(self, target_mmsi, send_priority): data_type = 0 #数据类型 target_MMSI = target_mmsi #目标MMSI priority = send_priority #优先级 # 打包为二进制 (大端字节序) content = struct.pack('>BIB', data_type, target_MMSI, priority) return content #长消息延续片段 def long_message_middle_frame(self, valid_binary_data): data_type = 1 #数据类型 data = valid_binary_data #有效数据 # 打包为二进制 (大端字节序) content = struct.pack('>B', data_type) + data return content #长消息结束片段 def long_message_end_frame(self): data_type = 2 #数据类型 # 打包为二进制 (大端字节序) content = struct.pack('>B', data_type) return content def create_message_packet(self, message, target_mmsi, send_priority): binary_data = message.encode('utf-8') message_frames = [] if len(binary_data) < 4: print("使用短消息,编码后的字节数小于4字节") return message_frames else: print(f"使用长消息编码后的字节数为{len(binary_data)}字节") chunks = [binary_data[i:i+self.chunk_size] for i in range(0, len(binary_data), self.chunk_size)] # 3. 检查总长度限制 if len(binary_data) > 256 * 1024: raise ValueError("总数据长度超过256KB限制") start_frame = self.long_message_start_frame(target_mmsi, send_priority) message_frames.append(self.create_tcp_packet(10, start_frame)) for chunk in chunks: middle_frame = self.long_message_middle_frame(chunk) message_frames.append(self.create_tcp_packet(10, middle_frame)) end_frame = self.long_message_end_frame() message_frames.append(self.create_tcp_packet(10, end_frame)) return message_frames def send_message(self): """启动Socket服务端""" Target_MMSI = self.MMSI # 示例目标MMSI Send_Priority = 1 # 示例发送优先级 message = self.message message_frames = self.create_message_packet(message, Target_MMSI, Send_Priority) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: try: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.connect((self.host, self.port)) print(f"Socket服务端已启动,监听 {self.host}:{self.port}") try: for message_frame in message_frames: print(f"发送报文: {message_frame.hex()}") sock.sendall(message_frame) # print("二进制表示:", ' '.join(format(byte, '08b') for byte in message_frame)) time.sleep(0.5) # time.sleep(3) sock.shutdown(socket.SHUT_WR) sock.close() except (ConnectionResetError, BrokenPipeError): print("客户端断开连接") except KeyboardInterrupt: print("\n服务端已停止") except Exception as e: print(f"服务端错误: {e}") # if __name__ == "__main__": # send_message()