Files

134 lines
5.2 KiB
Python
Raw Permalink Normal View History

2026-07-13 15:37:05 +08:00
import socket
import struct
def get_tcp_data(packet_data):
#判断帧头是否符合卓研
if packet_data[:4].decode('ascii') == '####':
print("开始解析报文帧")
packet_type = struct.unpack('>I', packet_data[4:8])[0] #获取报文类型 7为gps 12为ais
packet_lenth = struct.unpack('>I', packet_data[8:12])[0]
packet_content = packet_data[12:]
if packet_type == 7:
print(f"GPS内容长度: {packet_lenth} 字节")
data = get_gps_data(packet_content)
print(data)
elif packet_type == 12:
print(f"AIS内容长度: {packet_lenth} 字节")
data = get_ais_data(packet_content)
print(data)
def get_gps_data(packet_content):
fields = struct.unpack('>QiiiHHHBBIII', packet_content)
res = {}
res['utc_time'] = fields[0] # UTC时间 (8字节)
res['longitude'] = fields[1]/10000000 # 经度 (4字节东经120.5度)
res['latitude'] = fields[2]/10000000 # 纬度 (4字节北纬30.5度)
res['altitude'] = fields[3] # 海拔高度 (4字节50米)
res['used_sats'] = fields[4] # 定位使用的卫星数 (2字节)
res['gps_sats'] = fields[5] # GPS卫星数 (2字节)
res['beidou_sats'] = fields[6] # 北斗卫星数 (2字节)
res['gps_status'] = fields[7] # GPS状态 (1字节单点定位)
res['position_mode'] = fields[8] # 定位模式 (1字节3D定位)
res['hdop'] = fields[9]/10 # 水平精度因子 (4字节25.5米)
res['speed'] = fields[10]/100 # 运动速度 (4字节10.24节)
res['direction'] = fields[11] # 运动方向 (4字节359度)
return res
def get_ais_data(packet_content):
res ={}
demod_packet = packet_content[:9]
demod_data = packet_content[9:]
fields = struct.unpack('>BBBHHH', demod_packet)
res['message_type'] = fields[0]
res['satellite_id'] = fields[1]
res['demodulator_id'] = fields[2]
res['demod_slot'] = fields[3]
res['receive_delay'] = fields[4]
snr_packed = fields[5]
# 解析SNR
snr_int = (snr_packed >> 8) & 0xFF
snr_frac = snr_packed & 0xFF
res['snr'] = snr_int + snr_frac / 100.0
print(demod_data)
res['demod_data'] = get_demod_data(demod_data)
return res
def get_demod_data(bit_string):
# 如果输入是字节类型,先转换为二进制字符串
if isinstance(bit_string, bytes):
bit_string = ''.join(format(byte, '08b') for byte in bit_string)
pos = 0
decoded = {}
decoded['message_id'] = int(bit_string[pos:pos+6], 2) # 消息ID (6 bits)
pos += 6
decoded['repeat_indicator'] = int(bit_string[pos:pos+2], 2) # 转发指示符 (2 bits)
pos += 2
decoded['user_id'] = int(bit_string[pos:pos+30], 2) # 用户ID/MMSI (30 bits)
pos += 30
decoded['navigation_status'] = int(bit_string[pos:pos+4], 2) # 导航状态 (4 bits)
pos += 4
# 旋转速率 (8位有符号整数)
rot_value = int(bit_string[pos:pos+8], 2)
if rot_value > 127:
rot_value -= 256
decoded['rot'] = rot_value
pos += 8
decoded['sog'] = int(bit_string[pos:pos+10], 2) # 地面航速 (10 bits)
pos += 10
decoded['position_accuracy'] = int(bit_string[pos], 2) # 位置准确度 (1 bit)
pos += 1
# 经度 (28位)
longitude_value = int(bit_string[pos:pos+28], 2)
decoded['longitude'] = longitude_value / (60 * 10000) # 转换为度
pos += 28
# 纬度 (27位)
latitude_value = int(bit_string[pos:pos+27], 2)
decoded['latitude'] = latitude_value / (60 * 10000) # 转换为度
pos += 27
decoded['cog'] = int(bit_string[pos:pos+12], 2) # 地面航线 (12 bits)
pos += 12
decoded['true_heading'] = int(bit_string[pos:pos+9], 2) # 实际航向 (9 bits)
pos += 9
decoded['timestamp'] = int(bit_string[pos:pos+6], 2) # 时戳 (6 bits)
pos += 6
decoded['special_maneuver'] = int(bit_string[pos:pos+2], 2) # 特定操纵指示符 (2 bits)
pos += 2
decoded['spare'] = int(bit_string[pos:pos+3], 2) # 备用 (3 bits)
pos += 3
decoded['raim_flag'] = int(bit_string[pos], 2) # RAIM标志 (1 bit)
pos += 1
decoded['comm_state'] = int(bit_string[pos:pos+19], 2) # 通信状态 (19 bits)
return decoded
def receive_data():
"""接收数据"""
host = 'localhost'
port = 8082
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind((host, port))
print(f"监听 {host}:{port}...")
while True:
try:
data, addr = s.recvfrom(4096) # 接收缓冲区大小
print(f"\n收到来自 {addr} 的数据:")
print("原始数据(十六进制):", data.hex())
get_tcp_data(data)
except KeyboardInterrupt:
print("\n停止接收")
break
except Exception as e:
print(f"接收错误: {e}")
break
if __name__ == "__main__":
receive_data()