first commit
This commit is contained in:
115
code/vdes_utils/vdes_message_packaged.py
Normal file
115
code/vdes_utils/vdes_message_packaged.py
Normal file
@@ -0,0 +1,115 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user