app-starlock/lib/talk/startChart/p2p/p2p_manage.dart

109 lines
3.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'dart:io';
import 'package:star_lock/talk/startChart/proto/rbcu.pb.dart';
class P2pManage {
// 常量定义
static const String testMessage = 'Hello'; // 测试消息
static const int localPort = 0; // 绑定本地端口0 表示由系统分配)
static const Duration connectionTimeout = Duration(seconds: 5); // 连接超时时间
static const List<String> localNetworkPrefixes = [
'192.168.',
'10.',
'172.'
]; // 局域网 IP 前缀
RbcuInfo? communicationObjectRbcuInfo;
void init() {
// 初始化逻辑
}
// 解析 address 属性,提取对方的 IP 和端口
List<Map<String, String>> parseRemoteAddresses() {
final addresses = communicationObjectRbcuInfo?.address ?? [];
return addresses.map((addr) {
final parts = addr.split(':');
return {'ip': parts[0], 'port': parts[1]};
}).toList();
}
// 判断是否为局域网 IP
bool _isLocalNetworkIp(String ip) {
for (final prefix in localNetworkPrefixes) {
if (ip.startsWith(prefix)) {
// 处理 172.16.x.x 到 172.31.x.x
if (prefix == '172.') {
final secondOctet = int.tryParse(ip.split('.')[1]) ?? 0;
if (secondOctet >= 16 && secondOctet <= 31) {
return true;
}
} else {
return true;
}
}
}
return false;
}
// 创建 UDP 连接
Future<void> createUdpConnection() async {
final addresses = parseRemoteAddresses();
// 优先使用局域网 IP
addresses.sort((a, b) {
final isALocal = _isLocalNetworkIp(a['ip']!);
final isBLocal = _isLocalNetworkIp(b['ip']!);
if (isALocal && !isBLocal) return -1; // a 是局域网 IP优先级更高
if (!isALocal && isBLocal) return 1; // b 是局域网 IP优先级更高
return 0; // 优先级相同
});
// 尝试连接
for (final addr in addresses) {
final ip = addr['ip']!;
final port = int.parse(addr['port']!);
try {
final socket = await RawDatagramSocket.bind(
InternetAddress.anyIPv4, localPort); // 绑定本地端口
// 发送测试数据
final testData = testMessage.codeUnits;
socket.send(testData, InternetAddress(ip), port);
// 设置超时时间
final completer = Completer<void>();
// 监听响应
socket.listen((event) {
if (event == RawSocketEvent.read) {
final datagram = socket.receive();
if (datagram != null) {
final response = String.fromCharCodes(datagram.data);
print('收到来自 $ip:$port 的响应: $response');
completer.complete(); // 收到响应,完成 Future
}
}
});
// 等待响应或超时
try {
await completer.future.timeout(connectionTimeout);
print('成功连接到 $ip:$port');
return; // 连接成功,退出循环
} on TimeoutException {
print('连接到 $ip:$port 超时');
} finally {
socket.close(); // 关闭 socket
}
} catch (e) {
print('连接到 $ip:$port 失败: $e');
}
}
print('无法连接到任何地址');
}
}