From 834e4e056b8926cbf29fecae075ceab990ab76ec Mon Sep 17 00:00:00 2001 From: liyi Date: Mon, 2 Dec 2024 16:13:07 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E8=B0=83=E6=95=B4=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E4=B8=AD=E7=BB=A7=E5=8D=8F=E8=AE=AE=E4=B8=AD=E7=9A=84=E4=B8=8A?= =?UTF-8?q?=E6=8A=A5=E7=AD=BE=E5=90=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../startChart/entity/heartbeat_response.dart | 39 +++++++++++++++ lib/talk/startChart/entity/scp_message.dart | 48 ++++++++++++++----- lib/talk/startChart/start_chart_manage.dart | 3 +- 3 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 lib/talk/startChart/entity/heartbeat_response.dart diff --git a/lib/talk/startChart/entity/heartbeat_response.dart b/lib/talk/startChart/entity/heartbeat_response.dart new file mode 100644 index 00000000..263c3d42 --- /dev/null +++ b/lib/talk/startChart/entity/heartbeat_response.dart @@ -0,0 +1,39 @@ +class HeartbeatResponse { + int statusCode; // 状态码,1字节无符号 + int nextPingTime; // 下次ping时间秒数,2字节无符号 + + HeartbeatResponse({required this.statusCode, required this.nextPingTime}); + + @override + String toString() { + return 'HeartbeatResponse{statusCode: $statusCode, nextPingTime: $nextPingTime}'; + } + + // 反序列化方法 + static HeartbeatResponse deserialize(List bytes) { + if (bytes.length < 3) { + throw FormatException("Invalid HeartbeatResponse length"); + } + + final response = HeartbeatResponse( + statusCode: bytes[0], // 状态码,1字节 + nextPingTime: (bytes[2] << 8) | bytes[1], // 下次ping时间,2字节小端序 + ); + + return response; + } + + // 序列化方法 + static List serialize(HeartbeatResponse response) { + final List bytes = []; + + // 序列化状态码 + bytes.add(response.statusCode); + + // 序列化下次ping时间(2字节小端序) + bytes.add(response.nextPingTime & 0xFF); + bytes.add((response.nextPingTime >> 8) & 0xFF); + + return bytes; + } +} \ No newline at end of file diff --git a/lib/talk/startChart/entity/scp_message.dart b/lib/talk/startChart/entity/scp_message.dart index 3fc80678..fe3bd152 100644 --- a/lib/talk/startChart/entity/scp_message.dart +++ b/lib/talk/startChart/entity/scp_message.dart @@ -2,6 +2,8 @@ import 'dart:convert'; import 'package:crc32_checksum/crc32_checksum.dart'; import 'package:crypto/crypto.dart'; import 'package:star_lock/app_settings/app_settings.dart'; +import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; +import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart'; class ScpMessage { ScpMessage({ @@ -28,7 +30,7 @@ class ScpMessage { int? PayloadType; int? PayloadCRC; int? PayloadLength; - String? Payload; + dynamic Payload; // Payload可以是任何类型,这里用dynamic表示 ScpMessage.fromJson(dynamic json) { ProtocolFlag = json['ProtocolFlag']; @@ -58,9 +60,6 @@ class ScpMessage { 'PayloadLength': PayloadLength, 'Payload': Payload, }; - - - } @override @@ -190,7 +189,8 @@ class ScpMessage { // FromPeerId (字符串,长度固定为44字节) if (bytes.length - offset >= 44) { - message.FromPeerId = utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); + message.FromPeerId = + utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); offset += 44; } else { throw FormatException("Invalid FromPeerId length"); @@ -198,7 +198,8 @@ class ScpMessage { // ToPeerId (字符串,长度固定为44字节) if (bytes.length - offset >= 44) { - message.ToPeerId = utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); + message.ToPeerId = + utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); offset += 44; } else { throw FormatException("Invalid ToPeerId length"); @@ -226,22 +227,45 @@ class ScpMessage { print('PayloadLength bytes: ${bytes.sublist(offset, offset + 4)}'); message.PayloadLength = (bytes[offset] | - (bytes[offset + 1] << 8) | - (bytes[offset + 2] << 16) | - (bytes[offset + 3] << 24)); // 修正为 little-endian + (bytes[offset + 1] << 8) | + (bytes[offset + 2] << 16) | + (bytes[offset + 3] << 24)); // 修正为 little-endian offset += 4; } else { throw FormatException("Invalid PayloadLength length"); } // Payload (字符串,转换为字节) - if (message.PayloadLength != null && bytes.length - offset >= message.PayloadLength!) { - message.Payload = utf8.decode(bytes.sublist(offset, offset + message.PayloadLength!)); + if (message.PayloadLength != null && + bytes.length - offset >= message.PayloadLength!) { + message.Payload = + utf8.decode(bytes.sublist(offset, offset + message.PayloadLength!)); offset += message.PayloadLength!; } else { throw FormatException("Invalid Payload or PayloadLength"); } + // 解析Payload + // 解析Payload + if (message.PayloadType == 110) { // 假设110表示HeartbeatResponse类型 + if (message.PayloadLength != null && bytes.length - offset >= message.PayloadLength!) { + final payloadBytes = bytes.sublist(offset, offset + message.PayloadLength!); + message.Payload = HeartbeatResponse.deserialize(payloadBytes); + offset += message.PayloadLength!; + } else { + throw FormatException("Invalid Payload or PayloadLength"); + } + } else { + // 处理其他类型的Payload + if (message.PayloadLength != null && bytes.length - offset >= message.PayloadLength!) { + message.Payload = utf8.decode(bytes.sublist(offset, offset + message.PayloadLength!)); + offset += message.PayloadLength!; + } else { + throw FormatException("Invalid Payload or PayloadLength"); + } + } + + // 验证PayloadCRC // if (message.Payload != null) { // var crcBytes = List.from(utf8.encode(message.Payload!)); @@ -253,6 +277,7 @@ class ScpMessage { return message; } + // CRC-16 计算函数(示例实现,可能需要根据具体协议调整) static int _calculateCrc16(List data) { const poly = 0x8005; @@ -273,7 +298,6 @@ class ScpMessage { return crc; } - static String bytesToHex(List bytes) { return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(''); } diff --git a/lib/talk/startChart/start_chart_manage.dart b/lib/talk/startChart/start_chart_manage.dart index 1de800a0..9b060557 100644 --- a/lib/talk/startChart/start_chart_manage.dart +++ b/lib/talk/startChart/start_chart_manage.dart @@ -61,6 +61,7 @@ class StartChartManage { String ToPeerId = ''; // 对端ID String FromPeerId = ''; // 我的ID + // echo测试peer对端 final String echoPeerId = '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH'; // 星图服务初始化 @@ -217,7 +218,7 @@ class StartChartManage { // 发送消息 Future _sendMessage({required List message}) async { - _log(text: '发送给中继的消息体:${message},序列化之后的数据:【${bytesToHex(message)}】'); + // _log(text: '发送给中继的消息体:${message},序列化之后的数据:【${bytesToHex(message)}】'); var result = await _udpSocket?.send( message, InternetAddress(remoteHost), remotePort); if (result != message.length) {