public void ScanAsync(List <Tuple <IPAddress, string> > hostData, int[] ports, PortScannerOptions portScannerOptions, CancellationToken cancellationToken) { progressValue = 0; // Modify the ThreadPool for better performance ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads); ThreadPool.SetMinThreads(workerThreads + portScannerOptions.Threads, completionPortThreads + portScannerOptions.Threads); Task.Run(() => { foreach (Tuple <IPAddress, string> host in hostData) { try { ParallelOptions parallelOptions = new ParallelOptions() { CancellationToken = cancellationToken, MaxDegreeOfParallelism = portScannerOptions.Threads }; // foreach ip, Parallel.ForEach port... Parallel.ForEach(ports, parallelOptions, port => { // Test if port is open using (TcpClient tcpClient = host.Item1.AddressFamily == AddressFamily.InterNetworkV6 ? new TcpClient(AddressFamily.InterNetworkV6) : new TcpClient(AddressFamily.InterNetwork)) { IAsyncResult tcpClientConnection = tcpClient.BeginConnect(host.Item1, port, null, null); if (tcpClientConnection.AsyncWaitHandle.WaitOne(portScannerOptions.Timeout, false)) { try { tcpClient.EndConnect(tcpClientConnection); OnPortScanned(new PortScannedArgs(host, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Open)); } catch { if (portScannerOptions.ShowClosed) { OnPortScanned(new PortScannedArgs(host, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Closed)); } } } else { if (portScannerOptions.ShowClosed) { OnPortScanned(new PortScannedArgs(host, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Closed)); } } } // Increase the progress Interlocked.Increment(ref progressValue); OnProgressChanged(); }); } catch (OperationCanceledException) // If user has canceled { OnUserHasCanceled(); break; } } OnScanComplete(); }); // Reset the ThreadPool to defaul ThreadPool.SetMinThreads(workerThreads, completionPortThreads); }
public void ScanAsync(IPAddress[] ipAddresses, int[] ports, CancellationToken cancellationToken) { _progressValue = 0; // Modify the ThreadPool for better performance ThreadPool.GetMinThreads(out var workerThreads, out var completionPortThreads); ThreadPool.SetMinThreads(workerThreads + HostThreads + PortThreads, completionPortThreads + HostThreads + PortThreads); Task.Run(() => { try { var hostParallelOptions = new ParallelOptions { CancellationToken = cancellationToken, MaxDegreeOfParallelism = HostThreads }; var portParallelOptions = new ParallelOptions { CancellationToken = cancellationToken, MaxDegreeOfParallelism = PortThreads / HostThreads }; Parallel.ForEach(ipAddresses, hostParallelOptions, ipAddress => { // Resolve Hostname (PTR) var hostname = string.Empty; if (ResolveHostname) { try { Task.Run(() => { hostname = Dns.GetHostEntryAsync(ipAddress).Result.HostName; }, cancellationToken); } catch (SocketException) { } } // Check each port Parallel.ForEach(ports, portParallelOptions, port => { // Test if port is open using (var tcpClient = ipAddress.AddressFamily == AddressFamily.InterNetworkV6 ? new TcpClient(AddressFamily.InterNetworkV6) : new TcpClient(AddressFamily.InterNetwork)) { var tcpClientConnection = tcpClient.BeginConnect(ipAddress, port, null, null); if (tcpClientConnection.AsyncWaitHandle.WaitOne(Timeout, false)) { try { tcpClient.EndConnect(tcpClientConnection); OnPortScanned(new PortScannedArgs(ipAddress, hostname, port, PortLookup.Lookup(port) .FirstOrDefault(x => x.Protocol == PortLookup.Protocol.Tcp), PortState.Open)); } catch { if (ShowClosed) { OnPortScanned(new PortScannedArgs(ipAddress, hostname, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.Tcp), PortState.Closed)); } } } else { if (ShowClosed) { OnPortScanned(new PortScannedArgs(ipAddress, hostname, port, PortLookup.Lookup(port) .FirstOrDefault(x => x.Protocol == PortLookup.Protocol.Tcp), PortState.Closed)); } } } // Increase the progress Interlocked.Increment(ref _progressValue); OnProgressChanged(); }); }); OnScanComplete(); } catch (OperationCanceledException) // If user has canceled { // Check if the scan is already complete... if (ports.Length * ipAddresses.Length == _progressValue) { OnScanComplete(); } else { OnUserHasCanceled(); } } finally { // Reset the ThreadPool to defaul ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); ThreadPool.SetMinThreads(workerThreads - HostThreads + PortThreads, completionPortThreads - HostThreads + PortThreads); } }, cancellationToken); }