109 lines
3.2 KiB
Dart
109 lines
3.2 KiB
Dart
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('无法连接到任何地址');
|
||
}
|
||
}
|