From 4b288a15c66eae25f30c43157f621c6a2e2fc9c7 Mon Sep 17 00:00:00 2001 From: jakeallen Date: Wed, 27 Mar 2024 00:28:05 +0800 Subject: [PATCH] new_test --- receive.py | 313 +++++++++++++++++++++++++++++++++++++++++++++++++++++ send.py | 84 ++++++++++++-- 2 files changed, 389 insertions(+), 8 deletions(-) diff --git a/receive.py b/receive.py index cc64e3a..fd6302a 100644 --- a/receive.py +++ b/receive.py @@ -85,8 +85,321 @@ class ReceiveApp: msg, addr = self.sk.recvfrom(1024) message_to_display = "Received: " + msg.decode() + " from " + str(addr) self.recv_text.insert(tk.END, message_to_display + "\n") + self.analysis_message(msg) + # 上行报文采用不定长帧 + """帧格式: + 0~3 帧头 BYTE[4] 4 固定为0x58443341 + + 4~7 流水号 UINT32 4 0x00000000~0xFFFFFFFF循环,用于判断帧连续 + + 8~13 时标(年月日时分秒) BYTE[6] 6 若报文类别为0x01、0x02、0x03,此时间为FPGA采到第一bit数据时间或者第一个脉冲的起始时间;若报文类别为0xFF,此时间为组包时的时间 + + 14~17 时标(秒内计数器) UINT32 4 + + 18 报文类型 BYTE 1 0x01:AIS通道1信息;0x02:AIS通道2信息;0x03:ACARS通道1信息;0x04:ACARS通道2信息;0x05:ACARS通道3信息;0x06:ACARS通道4信息;0x07:ADS-B信息;0x08:IFF信息;0xFF:工况。19~20数据长度UINT16 2指数据段的长度,不包括帧头、帧尾和其它字段。 + + 21~20+n 数据段 BYTE[n] n 根据报文类型区分 + + 21+n~23+n 帧尾 BYTE[3] 3 固定为0x334441 + """ + + # 解析下行报文 + def analysis_message(self, msg): + global water + getmessage = msg.decode() + + # 如果帧头不是0x58443341,则报文错误 + if getmessage[0:8] != "58443341": + first_type = "错误类型:帧头错误" + self.recv_text.insert(tk.END, first_type + "\n") + return + + #判断是否连续 + Water = '{:08X}'.format(water) + water = water + 1 + if getmessage[8:16] == Water: + k = "帧连续" + self.recv_text.insert(tk.END, k + "\n") + else: + k = "帧不连续,有漏帧" + self.recv_text.insert(tk.END, k + "\n") + + #汇报时间 + """ + 授时指令内容: + 0 年 UINT8 1 00-99,对应0x00-0x63,基数为2000,例如:2001年对应0x01,2099年对应0x63。 + 1 月 UINT8 1 01-12,对应0x01-0x0C + 2 日 UINT8 1 01-31,对应0x01-0x1F + 3 时 UINT8 1 00-23,对应0x00-0x17 + 4 分 UINT8 1 00-59,对应0x00-0x3B + 5 秒 UINT8 1 00-59,对应0x00-0x3B + 6-9 保留 UINT8 4 + """ + year = int(getmessage[16:18], 16) + 2000 + month = int(getmessage[18:20], 16) + day = int(getmessage[20:22], 16) + hour = int(getmessage[22:24], 16) + minute = int(getmessage[24:26], 16) + second = int(getmessage[26:28], 16) + self.recv_text.insert(tk.END, "当前时间为: " + str(year) + "年" + str(month) + "月" + str(day) + "日" + str( + hour) + "时" + str(minute) + "分" + str(second) + "秒\n") + + #秒内计数器 + one = int(getmessage[28:30],16) + two = int(getmessage[30:32],16) + three = int(getmessage[32:34], 16) + four = int(getmessage[34:36], 16) + self.recv_text.insert(tk.END, "秒内计数器: " + str(one) + "." + str(two) + "." + str(three) + "." + str(four) + "\n") + + #报文类型 + if getmessage[36:38] == "01": + k = "AIS通道1信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "AIS通道2信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "ACARS通道1信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "ACARS通道2信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "ACARS通道3信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "ACARS通道4信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "ADS-B信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "IFF信息" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + elif getmessage[36:38] == "02": + k = "工况" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + else: + k = "错误" + self.recv_text.insert(tk.END,"报文类型:" + k + "\n") + + #数据长度 + self.recv_text.insert(tk.END, "数据长度:" + getmessage[38:42] + "\n") + + + #AIS信息 + if True: #getmessage[36:38]=="01" or getmessage[36:38]=="02" + if getmessage[42:44] == "01" or getmessage[42:44] == "02" or getmessage[42:44] == "03": + k = "A类船位置报告消息" + self.recv_text.insert(tk.END, "消息ID:" + k + "\n") + elif getmessage[42:44] == "05": + k = "A类船的静态消息" + self.recv_text.insert(tk.END, "消息ID:" + k + "\n") + elif getmessage[42:44] == "12": + k = "B类船位置报告消息" + self.recv_text.insert(tk.END, "消息ID:" + k + "\n") + elif getmessage[42:44] == "24": + k = "B类船的静态消息" + self.recv_text.insert(tk.END, "消息ID:" + k + "\n") + else: + k = "错误" + self.recv_text.insert(tk.END, "消息ID:" + k + "\n") + + #用户ID + self.recv_text.insert(tk.END, "用户ID:" + getmessage[44:54] + "\n") + + #IMO编号 + self.recv_text.insert(tk.END, "IMO编号:" + getmessage[54:62] + "\n") + + #呼号 + self.recv_text.insert(tk.END, "呼号:" + getmessage[62:76] + "\n") + + #船名 + self.recv_text.insert(tk.END, "船名:" + getmessage[76:116] + "\n") + + #船舶和货物类型 + if getmessage[116:118] == "00": + k = "捕捞" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "01": + k = "拖船" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "02": + k = "拖船且推带长度超过200米或宽度超过25米" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "03": + k = "从事挖掘或水下作业" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "04": + k = "从事潜水作业" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "05": + k = "从事军事行动" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "06": + k = "帆船" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "07": + k = "游艇" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "21": + k = "运载DG、HS或者MP、IMO危险品或X(2)类污染物" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "32": + k = "运载DG、HS或者MP、IMO危险品或Y(2)类污染物" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "43": + k = "运载DG、HS或者MP、IMO危险品或Z(2)类污染物" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "50": + k = "引航船舶" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "51": + k = "搜救船舶" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "52": + k = "拖轮" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "53": + k = "港口补给船" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "54": + k = "安装有防污染设施或设备的船舶" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "55": + k = "执法船舶" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "58": + k = "医疗运输船舶" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "59": + k = "非武装冲突参与国的船舶和航空器" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "60": + k = "客轮" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "70": + k = "货轮" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + elif getmessage[116:118] == "80": + k = "油轮" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + else: + k = "错误" + self.recv_text.insert(tk.END, "船舶和货物类型:" + k + "\n") + + + # 船舶宽度 + self.recv_text.insert(tk.END, "船舶宽度:" + getmessage[118:122] + "\n") + + # 船舶长度 + self.recv_text.insert(tk.END, "船舶长度:" + getmessage[122:126] + "\n") + + #预计到达时间 + month = int(getmessage[126:128], 16) + day = int(getmessage[128:130], 16) + hour = int(getmessage[130:132], 16) + minute = int(getmessage[132:134], 16) + self.recv_text.insert(tk.END, "预计到达时间为: " + str(month) + "月" + str(day) + "日" + str( + hour) + "时" + str(minute) + "分" "\n") + + #目前最大静态吃水 + k = int(getmessage[134:136],16) + k = k / 10 + self.recv_text.insert(tk.END, "目前最大静态吃水:" + str(k) + "米\n") + + #目的地 + self.recv_text.insert(tk.END, "目的地:" + getmessage[136:176] + "\n") + + #导航状态 + if getmessage[176:178] == "00": + k = "发动机使用中" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "01": + k = "锚泊" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "02": + k = "未操纵" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "03": + k = "有限适航性" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "04": + k = "受船舶吃水限制" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "05": + k = "系泊" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "06": + k = "搁浅" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "07": + k = "从事捕捞" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "08": + k = "航行中" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + elif getmessage[176:178] == "15": + k = "无效信息" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + else: + k = "错误" + self.recv_text.insert(tk.END, "导航状态:" + k + "\n") + + + #地面航速 + k = int(getmessage[178:182],16) / 10 + self.recv_text.insert(tk.END, "地面航速:" + k + "\n") + + + #经纬度 + get_longitude = getmessage[182:190] + if get_longitude[0:3] == "FFFF": + longitude = "无效" + else: + byte_string = bytes.fromhex(get_longitude) + longitude = int.from_bytes(byte_string, byteorder='little', signed=True) + if (longitude < 0): + long_tag = "南纬: " + longitude = str((0 - longitude) / 10000) + else: + long_tag = "北纬: " + longitude = str((longitude) / 10000) + get_latitude = getmessage[190:198] + if get_latitude[0:3] == "FFFF": + latitude = "无效" + else: + byte_string = bytes.fromhex(get_latitude) + latitude = int.from_bytes(byte_string, byteorder='little', signed=True) + if (latitude < 0): + lat_tag = " 西经: " + latitude = str((0 - latitude) / 10000) + else: + lat_tag = " 东经:" + latitude = str((latitude) / 10000) + if (longitude == "无效" or latitude == "无效"): + self.recv_text.insert(tk.END, "无效位置\n") + else: + self.recv_text.insert(tk.END, "本机位置为: " + str(long_tag) + str(longitude) + str(lat_tag) + str( + latitude) + "\n") + + #地面航线 + k = int(getmessage[198:202],16) / 10 + self.recv_text.insert(tk.END, "地面航线:" + k + "\n") + + # 实际航向 + k = int(getmessage[202:206], 16) + self.recv_text.insert(tk.END, "实际航向:" + k + "\n") + + #帧尾 + if getmessage[206:212] != "334441": + last_type = "错误类型:帧尾错误" + self.recv_text.insert(tk.END, last_type + "\n") + return + if __name__ == "__main__": + water = 0 root = tk.Tk() app = ReceiveApp(root) root.mainloop() diff --git a/send.py b/send.py index f2d671d..0b67215 100644 --- a/send.py +++ b/send.py @@ -5,23 +5,80 @@ from threading import Thread import socket import time + class SendApp: def __init__(self, window): self.window = window self.window.title("Send端") - # 发送区域 + # 创建发送区域的主框架 self.send_frame = tk.Frame(window) self.send_frame.pack(padx=10, pady=10) - self.send_label = tk.Label(self.send_frame, text="发送数据") - self.send_label.pack(side=tk.LEFT) + # 创建专门的发送数据子框架 + self.send_data_frame = tk.Frame(self.send_frame) + self.send_data_frame.pack(side=tk.TOP, fill=tk.X, expand=True) - self.send_entry = tk.Entry(self.send_frame) + self.send_label = tk.Label(self.send_data_frame, text="发送数据") + self.send_label.pack(side=tk.LEFT) + self.send_entry = tk.Entry(self.send_data_frame, width=90) self.send_entry.pack(side=tk.LEFT) - self.send_button = tk.Button(self.send_frame, text="发送", command=self.send_message) - self.send_button.pack(side=tk.LEFT) + # 输入帧头 + self.first_message_label = tk.Label(self.send_frame, text="帧头:") + self.first_message_label.pack(side=tk.LEFT) + self.first_message_entry = tk.Entry(self.send_frame) + self.first_message_entry.pack(side=tk.LEFT) + + # 流水号 + self.flow_msg_label = tk.Label(self.send_frame, text="流水号:") + self.flow_msg_label.pack(side=tk.LEFT) + self.flow_msg_entry = tk.Entry(self.send_frame) + self.flow_msg_entry.pack(side=tk.LEFT) + + # 时标 + self.time_msg_label = tk.Label(self.send_frame, text="时标:") + self.time_msg_label.pack(side=tk.LEFT) + self.time_msg_entry = tk.Entry(self.send_frame) + self.time_msg_entry.pack(side=tk.LEFT) + + # 时标(秒内计数器) + self.sec_time_msg_label = tk.Label(self.send_frame, text="时标(秒内计数器):") + self.sec_time_msg_label.pack(side=tk.LEFT) + self.sec_time_msg_entry = tk.Entry(self.send_frame) + self.sec_time_msg_entry.pack(side=tk.LEFT) + + # 报文类型 + self.type_msg_label = tk.Label(self.send_frame, text="报文类型:") + self.type_msg_label.pack(side=tk.LEFT) + self.type_msg_entry = tk.Entry(self.send_frame) + self.type_msg_entry.pack(side=tk.LEFT) + + # 数据长度 + self.length_msg_label = tk.Label(self.send_frame, text="数据长度:") + self.length_msg_label.pack(side=tk.LEFT) + self.length_msg_entry = tk.Entry(self.send_frame) + self.length_msg_entry.pack(side=tk.LEFT) + + # 数据段 + self.data_msg_label = tk.Label(self.send_frame, text="数据段:") + self.data_msg_label.pack(side=tk.LEFT) + self.data_msg_entry = tk.Entry(self.send_frame) + self.data_msg_entry.pack(side=tk.LEFT) + + # 输入帧尾 + self.last_message_label = tk.Label(self.send_frame, text="帧尾:") + self.last_message_label.pack(side=tk.LEFT) + self.last_message_entry = tk.Entry(self.send_frame) + self.last_message_entry.pack(side=tk.LEFT) + + # 创建一个包含发送按钮的框架 + self.send_button_frame = tk.Frame(self.send_frame) + self.send_button_frame.pack(fill=tk.X, padx=10, pady=10) # 框架会填充整个水平方向 + + # 将发送按钮放入这个新的框架,并让它在框架中居中 + self.send_button = tk.Button(self.send_button_frame, text="发送", command=self.send_message) + self.send_button.pack(side=tk.TOP, pady=10) # 这里不需要使用 anchor 参数,因为框架是填充整个水平方向的 # 接收区域 self.recv_frame = tk.Frame(window) @@ -29,13 +86,14 @@ class SendApp: self.recv_text = tk.Text(self.recv_frame, height=40, width=50) self.recv_text.pack(expand=True, fill="both") - #创建udp对象 + + # 创建udp对象 self.sk = socket.socket(type=socket.SOCK_DGRAM) self.sk.bind(("127.0.0.1", 5010)) # 开始接收数据的线程 self.thread = Thread(target=self.receive_data) - #运行解析下行报文函数 + # 运行解析下行报文函数 self.thread.daemon = True self.thread.start() @@ -43,6 +101,16 @@ class SendApp: def send_message(self): msg = self.send_entry.get() + if msg == "": + head = self.first_message_entry.get() + flow = self.flow_msg_entry.get() + times = self.time_msg_entry.get() + time_count = self.time_msg_entry.get() + types = self.type_msg_entry.get() + length = self.length_msg_entry.get() + data = self.data_msg_entry.get() + last = self.last_message_entry.get() + msg = head + flow + times + time_count + types + length + data + last #发送数据 self.sk.sendto(msg.encode(), ("127.0.0.1", 9000)) time.sleep(1)