ping static method
Future<IcmpResult?>
ping(
- InternetAddress ipv4Address, {
- Duration timeout = const Duration(seconds: 1),
- int sizeToSend = 32,
- int replyBufferSize = 1024,
Implementation
static Future<IcmpResult?> ping(
InternetAddress ipv4Address, {
Duration timeout = const Duration(seconds: 1),
int sizeToSend = 32,
int replyBufferSize = 1024,
}) async {
if (ipv4Address.type != InternetAddressType.IPv4) {
throw Exception('Only IPv4 address is supported');
}
final ipv4 = ipv4Address.rawAddress;
final ipv4int =
(ipv4[3] << 24) | (ipv4[2] << 16) | (ipv4[1] << 8) | ipv4[0];
final hEvent = _Kernel32.createEvent(0, 1, 0, 0);
final toSend = calloc<Uint8>(sizeToSend);
final replyBuffer = calloc<_ICMP_ECHO_REPLY>(replyBufferSize);
final icmp = _IcmpApi.icmpOpenFile();
const WAIT_TIMEOUT = 0x102;
const ERROR_IO_PENDING = 997;
try {
final result = _IcmpApi.icmpSendEcho2(
icmp,
hEvent,
0,
0,
ipv4int,
toSend,
sizeToSend,
0,
replyBuffer,
replyBufferSize,
timeout.inMilliseconds,
);
if (result != 0) return null;
// final error = _Kernel32.getLastError();
// if (error != ERROR_IO_PENDING) return null;
for (;;) {
final result = _Kernel32.waitForSingleObject(hEvent, 0);
if (result == 0) {
final result = replyBuffer.ref;
return IcmpResult(
status: result.status,
roundTripTime: Duration(milliseconds: result.roundTripTime),
ttl: result.ttl);
} else if (result != WAIT_TIMEOUT) {
return null;
}
await Future.delayed(
Duration(milliseconds: min(100, timeout.inMilliseconds)));
}
} finally {
_IcmpApi.icmpCloseHandle(icmp);
calloc.free(toSend);
calloc.free(replyBuffer);
_Kernel32.closeHandle(hEvent);
}
}