/// <summary> /// Asynchronously returns a collection of IPHostEntries of all computers found in the NetworkNeighborhood /// </summary> /// <returns></returns> private async Task <ICollection <IPHostEntry> > DoGetHostsAsync() { var stopWatch = System.Diagnostics.Stopwatch.StartNew(); var networks = NetworkUtils.GetAllLocalIPv4Networks(); ServiceRegistration.Get <ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: Found {0} local IPv4 network(s) with IP address(es) {1}", networks.Count, String.Join(" / ", networks.Select(i => i.Address + " (" + i.IPv4Mask + ")"))); networks = RemoveLargeSubnets(networks); ServiceRegistration.Get <ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: {0} local IPv4 network(s) are used: {1}", networks.Count, String.Join(" / ", networks.Select(i => i.Address + " (" + i.IPv4Mask + ")"))); var tasks = new Dictionary <IPAddress, Task <NbNsNodeStatusResponse> >(); using (var client = new NbNsClient()) { foreach (var target in networks.SelectMany(NetworkUtils.GetAllAddressesInSubnet)) { if (!tasks.ContainsKey(target)) { tasks.Add(target, client.SendUnicastNodeStatusRequestAsync(NbNsNodeStatusRequest.WildCardNodeStatusRequest, target)); } } await Task.WhenAll(tasks.Values); // Uncomment the following two lines for extensive logging // foreach (var kvp in tasks.Where(kvp => kvp.Value.Result != null)) // ServiceRegistration.Get<ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: Found {0} ({1})\r\n{2}", kvp.Value.Result.WorkstationName, kvp.Key, kvp.Value.Result); } // If the computer has multiple network interfaces, it is found multiple times - once for each network interface. // Every occurence of the computer then has a different IP address (the one of the respective network interface). // As result we want this computer only as one IPHostEntry, but IPHostEntry.AddressList should show all IP addresses. var result = new HashSet <IPHostEntry>(); var responses = tasks.Where(kvp => kvp.Value.Result != null); foreach (var kvp in responses) { var alreadyPresentHost = result.FirstOrDefault(host => host.HostName == kvp.Value.Result.WorkstationName); if (alreadyPresentHost == null) { result.Add(new IPHostEntry { AddressList = new[] { kvp.Key }, HostName = kvp.Value.Result.WorkstationName }); } else { if (!alreadyPresentHost.AddressList.Any(address => address.Equals(kvp.Key))) { alreadyPresentHost.AddressList = alreadyPresentHost.AddressList.Union(new[] { kvp.Key }).ToArray(); } } } NeighborhoodBrowserHelper.LogResult(result, GetType().Name, stopWatch.ElapsedMilliseconds); return(result); }
/// <summary> /// Asynchronously returns a collection of IPHostEntries of all computers found in the NetworkNeighborhood /// </summary> /// <returns></returns> private async Task<ICollection<IPHostEntry>> DoGetHostsAsync() { var stopWatch = System.Diagnostics.Stopwatch.StartNew(); var networks = NetworkUtils.GetAllLocalIPv4Networks(); ServiceRegistration.Get<ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: Found {0} local IPv4 network(s) with IP address(es) {1}", networks.Count, String.Join(" / ", networks.Select(i => i.Address + " (" + i.IPv4Mask + ")"))); networks = RemoveLargeSubnets(networks); ServiceRegistration.Get<ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: {0} local IPv4 network(s) are used: {1}", networks.Count, String.Join(" / ", networks.Select(i => i.Address + " (" + i.IPv4Mask + ")"))); var tasks = new Dictionary<IPAddress, Task<NbNsNodeStatusResponse>>(); using (var client = new NbNsClient()) { foreach (var target in networks.SelectMany(NetworkUtils.GetAllAddressesInSubnet)) tasks.Add(target, client.SendUnicastNodeStatusRequestAsync(NbNsNodeStatusRequest.WildCardNodeStatusRequest, target)); await Task.WhenAll(tasks.Values); // Uncomment the following two lines for extensive logging // foreach (var kvp in tasks.Where(kvp => kvp.Value.Result != null)) // ServiceRegistration.Get<ILogger>().Debug("NetbiosNameServiceNeighborhoodBrowser: Found {0} ({1})\r\n{2}", kvp.Value.Result.WorkstationName, kvp.Key, kvp.Value.Result); } // If the computer has multiple network interfaces, it is found multiple times - once for each network interface. // Every occurence of the computer then has a different IP address (the one of the respective network interface). // As result we want this computer only as one IPHostEntry, but IPHostEntry.AddressList should show all IP addresses. var result = new HashSet<IPHostEntry>(); var responses = tasks.Where(kvp => kvp.Value.Result != null); foreach (var kvp in responses) { var alreadyPresentHost = result.FirstOrDefault(host => host.HostName == kvp.Value.Result.WorkstationName); if (alreadyPresentHost == null) result.Add(new IPHostEntry { AddressList = new[] { kvp.Key }, HostName = kvp.Value.Result.WorkstationName }); else { if (!alreadyPresentHost.AddressList.Any(address => address.Equals(kvp.Key))) alreadyPresentHost.AddressList = alreadyPresentHost.AddressList.Union(new[] { kvp.Key }).ToArray(); } } NeighborhoodBrowserHelper.LogResult(result, GetType().Name, stopWatch.ElapsedMilliseconds); return result; }