136 lines
3.6 KiB
Dart
136 lines
3.6 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:udp/udp.dart';
|
|
|
|
class UdpService {
|
|
/// Send a package to a single IP address
|
|
Future<bool> sendPackage({
|
|
required String data,
|
|
required String ipAddress,
|
|
required int port,
|
|
}) async {
|
|
UDP? sender;
|
|
try {
|
|
// Create UDP instance
|
|
sender = await UDP.bind(Endpoint.any());
|
|
|
|
// Convert data to bytes
|
|
final dataBytes = utf8.encode(data);
|
|
|
|
// Parse IP address
|
|
final address = InternetAddress(ipAddress);
|
|
|
|
// Create endpoint
|
|
final destination = Endpoint.unicast(address, port: Port(port));
|
|
|
|
// Send the packet
|
|
final bytesSent = await sender.send(dataBytes, destination);
|
|
|
|
// Give a small delay to ensure packet is sent
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
|
|
return bytesSent > 0;
|
|
} catch (e) {
|
|
// Error occurred while sending UDP package
|
|
return false;
|
|
} finally {
|
|
// Always close the socket
|
|
sender?.close();
|
|
}
|
|
}
|
|
|
|
/// Send a broadcast package to all devices on the network
|
|
Future<bool> sendBroadcast({
|
|
required String data,
|
|
required int port,
|
|
String broadcastAddress = '255.255.255.255',
|
|
}) async {
|
|
UDP? sender;
|
|
try {
|
|
// Create UDP instance
|
|
sender = await UDP.bind(Endpoint.any());
|
|
|
|
// Convert data to bytes
|
|
final dataBytes = utf8.encode(data);
|
|
|
|
// Parse broadcast address
|
|
final address = InternetAddress(broadcastAddress);
|
|
|
|
// Create broadcast endpoint - Endpoint.broadcast takes only port
|
|
final destination = Endpoint.broadcast(port: Port(port));
|
|
|
|
// Send the broadcast packet
|
|
final bytesSent = await sender.send(dataBytes, destination);
|
|
|
|
// Give a small delay to ensure packet is sent
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
|
|
return bytesSent > 0;
|
|
} catch (e) {
|
|
// Error occurred while sending broadcast package
|
|
return false;
|
|
} finally {
|
|
// Always close the socket
|
|
sender?.close();
|
|
}
|
|
}
|
|
|
|
/// Send a package to multiple IP addresses
|
|
/// Returns a map of IP address to success status
|
|
Future<Map<String, bool>> sendToMultipleIps({
|
|
required String data,
|
|
required List<String> ipAddresses,
|
|
required int port,
|
|
}) async {
|
|
final results = <String, bool>{};
|
|
|
|
for (final ip in ipAddresses) {
|
|
final success = await sendPackage(
|
|
data: data,
|
|
ipAddress: ip,
|
|
port: port,
|
|
);
|
|
results[ip] = success;
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/// Send a package with support for broadcast mode and multiple IPs
|
|
/// Returns a map of targets (IP addresses or "broadcast") to success status
|
|
Future<Map<String, bool>> sendPackageAdvanced({
|
|
required String data,
|
|
required int port,
|
|
bool isBroadcast = false,
|
|
List<String>? ipAddresses,
|
|
String broadcastAddress = '255.255.255.255',
|
|
}) async {
|
|
if (isBroadcast) {
|
|
// Send broadcast
|
|
final success = await sendBroadcast(
|
|
data: data,
|
|
port: port,
|
|
broadcastAddress: broadcastAddress,
|
|
);
|
|
return {'broadcast': success};
|
|
} else if (ipAddresses != null && ipAddresses.isNotEmpty) {
|
|
// Send to multiple IPs
|
|
return await sendToMultipleIps(
|
|
data: data,
|
|
ipAddresses: ipAddresses,
|
|
port: port,
|
|
);
|
|
} else {
|
|
// Fallback to localhost
|
|
final success = await sendPackage(
|
|
data: data,
|
|
ipAddress: '127.0.0.1',
|
|
port: port,
|
|
);
|
|
return {'127.0.0.1': success};
|
|
}
|
|
}
|
|
}
|
|
|
|
|