scan method

Future<ScanResult> scan()

Execute scanning with at least 1 isolates

Implementation

Future<ScanResult> scan() async {
  // Prepare port ranges for isolates
  var isolatePorts = <List<int>>[];
  var portsPerIsolate = (_ports.length / _isolatesCount).ceil();
  var startIndex = 0;
  var endIndex = 0;
  var ports = List<int>.from(_ports);

  if (_shuffle) ports.shuffle();
  while (startIndex < ports.length) {
    endIndex = startIndex + portsPerIsolate > ports.length ? ports.length : startIndex + portsPerIsolate;
    isolatePorts.add(ports.sublist(startIndex, endIndex));
    startIndex = endIndex;
  }
  // Scan result
  _isolateScanResults = [];
  _scanResult = ScanResult(host: _host, ports: _ports, status: ScanStatuses.scanning);
  // Run isolates and create listeners
  var completers = <Completer>[];
  for (var portsList in isolatePorts) {
    var completer = Completer();
    var receivePort = ReceivePort();
    var isolateScanResult = ScanResult(host: _host, ports: portsList, status: ScanStatuses.scanning);
    completers.add(completer);
    _isolateScanResults.add(isolateScanResult);
    await Isolate.spawn(_isolateScan,
        IsolateArguments(receivePort.sendPort, _host, portsList, _connectTimeout, updateInterval: _updateInterval));
    receivePort.listen((result) {
      // When response received add information to scanResult
      isolateScanResult.scanned = result.scanned;
      isolateScanResult.open = result.open;
      isolateScanResult.closed = result.closed;
      isolateScanResult.status = result.status;
      if (result.status == ScanStatuses.finished) {
        receivePort.close();
        completer.complete(result);
      }
    });
  }
  // Wait until all isolates finished
  await Future.wait(completers.map((completer) => completer.future));
  _scanResult.status = ScanStatuses.finished;
  completers.clear();
  return scanResult;
}