Files
VDES_Backend/code/vdes_utils/vdes_message_packaged.py

115 lines
4.5 KiB
Python
Raw Permalink Normal View History

2026-07-13 15:37:05 +08:00
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()