Files
VDES_Backend/code/vdes_utils/vdes_message_packaged.py
2026-07-13 15:37:05 +08:00

115 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()