zero_network_kit 1.0.1 copy "zero_network_kit: ^1.0.1" to clipboard
zero_network_kit: ^1.0.1 copied to clipboard

Network diagnostics toolkit for Flutter: connectivity, ping, DNS, speed test, port scan and quality scoring across Android, iOS, macOS, Windows and Linux.

zero_network_kit #

English  |  简体中文

A Flutter plugin for network diagnostics: connectivity inspection, latency probing, DNS resolution, port checks, bandwidth measurement, quality scoring and micro-benchmarks — for Android, iOS, macOS, Windows, Linux and Web (partial).

pub version pub points CI License: MPL-2.0 Platform Flutter Dart Style: effective dart

🔔 Upgrade recommended: 1.0.1 adds partial Web support — the plugin now compiles and runs in the browser, and the capabilities the sandbox forbids degrade gracefully instead of failing. It also fixes the speed test on the web. Upgrade to ^1.0.1.

🌐 Official Website  ·  📦 View on pub.flutter-io.cn  ·  🔗 View on GitHub


Table of Contents #


Features #

Capability API Notes
Connectivity NetworkDiagnostic.checkConnection() Transport, IPv4/IPv6, gateway, SSID, RSSI, MAC, VPN
Connectivity stream NetworkDiagnostic.onConnectivityChanged Emits a fresh snapshot on every change
Latency NetworkDiagnostic.ping() TCP handshake RTT everywhere; system ICMP on desktop
DNS NetworkDiagnostic.resolve() system resolver + raw UDP against explicit servers
Bandwidth NetworkDiagnostic.runSpeedTest() Download/upload throughput with progress callbacks
Ports NetworkDiagnostic.checkPort() / scanPorts() Bounded-concurrency TCP reachability
Quality NetworkDiagnostic.evaluateQuality() Weighted 0–100 score + level + suggestions
Full report NetworkDiagnostic.diagnose() One-shot aggregate of every probe
Capabilities NetworkDiagnostic.capabilities Query-then-call; hide unsupported cards (e.g. SSID on desktop)
Benchmarks NetworkBenchmark.runAll() Measures how fast the diagnostics API itself runs

Design goals:

  • Hermetic unit tests — every service accepts injected collaborators (ConnectivityAdapter, http.Client, PingService, …), so the whole test suite runs without touching the network.
  • No hidden state — results are immutable value objects with toMap().
  • Graceful degradation — a missing permission or an unreachable sub-service never throws through the public API; the corresponding field stays null.

Getting started #

dependencies:
  zero_network_kit: ^1.0.1

Android permissions #

The plugin manifest already declares INTERNET, ACCESS_NETWORK_STATE and ACCESS_WIFI_STATE. Reading the Wi-Fi SSID additionally requires location permission (ACCESS_FINE_LOCATION) on Android 8.1+ and the Access WiFi Information entitlement plus location authorisation on iOS. Without it the snapshot simply reports ssid: null.

Usage #

The snippets below cover the common paths. For every method, parameter, default and result field, see the API guide.

import 'package:zero_network_kit/zero_network_kit.dart';

void main() {
  // Optional: apply global defaults once.
  ZeroNetworkKit.init(
    config: const NetworkDiagnosticConfig(
      pingHost: '1.1.1.1',
      dnsServers: <String>['1.1.1.1', '8.8.8.8'],
    ),
  );
  runApp(const MyApp());
}

Connectivity #

final info = await NetworkDiagnostic.checkConnection(probeReachability: true);

print('${info.type.label} · ${info.ipAddress} · ${info.signalStrength} dBm');
print('gateway=${info.gateway} vpn=${info.isVpn} reachable=${info.isReachable}');

await for (final change in NetworkDiagnostic.onConnectivityChanged) {
  print('now on ${change.type.id}');
}

Just need connectivity? You don't need init() or any of the other APIs — checkConnection() and onConnectivityChanged work out of the box. See the Connectivity-only: minimal example in the Connectivity chapter of API.md.

Ping #

final result = await NetworkDiagnostic.ping(host: '1.1.1.1', count: 5);

print('${result.received}/${result.sent} replies, '
      'loss ${result.packetLoss.toStringAsFixed(1)}%, '
      'avg ${result.averageTime.toStringAsFixed(1)} ms, '
      'jitter ${result.jitter.toStringAsFixed(2)} ms');

On desktop you can switch to the system ICMP binary:

await NetworkDiagnostic.ping(host: '1.1.1.1', mode: PingMode.icmp);

DNS #

final results = await NetworkDiagnostic.resolve(
  domain: 'example.com',
  dnsServers: const <String>['1.1.1.1', '8.8.8.8'],
  includeSystemResolver: true,
);

for (final r in results) {
  print('${r.server}: ${r.isSuccess ? r.resolvedIps.join(", ") : r.errorMessage}'
        ' (${r.responseTimeMs.toStringAsFixed(1)} ms)');
}

Speed test #

final speed = await NetworkDiagnostic.runSpeedTest(
  onProgress: (progress) => print(
    '${progress.phase.name}: ${progress.speedMbps.toStringAsFixed(1)} Mbps',
  ),
);

print('↓ ${speed.downloadSpeed.toStringAsFixed(2)} Mbps  '
      '↑ ${speed.uploadSpeed.toStringAsFixed(2)} Mbps');

Download and upload phases write a meaningful amount of traffic. Defaults point at the public Cloudflare speed endpoints; override downloadUrl / uploadUrl to use your own.

Ports #

if (await NetworkDiagnostic.isPortOpen(host: 'example.com', port: 443)) {
  print('HTTPS reachable');
}

final scan = await NetworkDiagnostic.scanPorts(
  host: 'example.com',
  ports: const <int>[22, 80, 443, 8080],
  concurrency: 8,
);

Quality score #

final score = await NetworkDiagnostic.evaluateQuality(includeSpeedTest: false);

print('${score.score}/100 (${score.level.label})');
for (final suggestion in score.suggestions) {
  print('• $suggestion');
}

The score is a weighted average of the metrics that are available:

Metric Weight Source
latency 0.25 PingResult.averageTime
jitter 0.10 PingResult.jitter
packetLoss 0.15 PingResult.packetLoss
download 0.25 SpeedTestResult.downloadSpeed
upload 0.15 SpeedTestResult.uploadSpeed
dns 0.10 mean successful DnsTestResult.responseTimeMs
signalStrength 0.10 NetworkConnectionInfo.signalStrength

Tune the ideal values with NetworkDiagnosticConfig(qualityTargets: ...).

Full report #

final report = await NetworkDiagnostic.diagnose(includePorts: true);

print(report); // NetworkDiagnosticReport(type: wifi, connected: true, score: 87.5)
print(report.toMap()); // JSON encodable

Benchmarks #

final suite = await NetworkBenchmark.runAll(iterations: 20, warmupIterations: 3);

for (final result in suite.results) {
  print('${result.testName}: avg '
        '${(result.averageDuration.inMicroseconds / 1000).toStringAsFixed(2)} ms, '
        '${result.operationsPerSecond.toStringAsFixed(1)} ops/s');
}

Benchmarks answer questions like "how expensive is one checkConnection() call on this device?" — useful when deciding whether a diagnostic belongs on the startup path.

Testing your own code against it #

Every service is injectable, so you can unit-test your integration points without a network:

class FakeConnectivityAdapter implements ConnectivityAdapter {
  @override
  Future<List<String>> checkConnectivity() async => <String>['wifi'];

  @override
  Stream<List<String>> get onConnectivityChanged => const Stream.empty();
}

NetworkDiagnostic.configure(
  connectivity: ConnectivityService(adapter: FakeConnectivityAdapter()),
);

NetworkDiagnostic.reset() restores the built-in defaults.

Platform support #

Platform Status
Android ✅ Supported (Kotlin native side)
iOS ✅ Supported (Swift native side)
macOS ✅ Supported (Swift native side)
Windows ✅ Supported (C++ native side)
Linux ✅ Supported (C++ native side)
Web ⚠️ Partial — see Web support below

Web support #

The web build exposes the same static API. Capabilities that the browser sandbox forbids degrade gracefully — they return null or an "unavailable" result instead of throwing:

Capability Web Notes
Connectivity via connectivity_plus
Ping (PingMode.tcp) ⚠️ HTTPS round trip; the target must send CORS headers
Ping (PingMode.icmp) throws UnsupportedError
DNS (system resolver) via DNS-over-HTTPS
DNS (explicit server) ⚠️ needs a DoH endpoint, otherwise "unsupported"
Speed test HTTP download / upload
Quality score pure function
Benchmark pure function
Port check / scan returns "unavailable" results
Native details (SSID, gateway, MAC, VPN) null

ZeroNetworkKit.getNativeNetworkDetails() returns null on the web and ZeroNetworkKit.getPlatformVersion() returns Web. Call NetworkCapabilities.current() to discover the supported set at runtime.

Documentation #

  • API.md — complete usage guide: every public API with copy-paste examples, parameter defaults, model reference and common pitfalls.
  • AGENTS.md — engineering contract: architecture, conventions and the new-feature checklist.
  • CONTRIBUTING.md — how to set up and submit changes.
  • CHANGELOG.md — release history.

License #

MPL-2.0 © Zero Labs

Third-party dependency, trademark and endorsement notices live in NOTICE.

0
likes
150
points
--
downloads

Documentation

Documentation
API reference

Publisher

verified publisherzerolabsco.com

Network diagnostics toolkit for Flutter: connectivity, ping, DNS, speed test, port scan and quality scoring across Android, iOS, macOS, Windows and Linux.

Repository (GitHub)
View/report issues
Contributing

Topics

#network #diagnostics #speed-test #ping #dns

License

MPL-2.0 (license)

Dependencies

connectivity_plus, flutter, flutter_web_plugins, http, plugin_platform_interface

More

Packages that depend on zero_network_kit

Packages that implement zero_network_kit