scan method
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;
}