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()