/// <summary> /// Discover devices in LAN /// </summary> /// <returns></returns> public static async IAsyncEnumerable <Device> DiscoverAndEnumerateAsync(CancellationToken?cancel = null) { List <Task <IEnumerable <Device> > > tasks = NetworkInterface.GetAllNetworkInterfaces() .Where(networkInterface => networkInterface.OperationalStatus == OperationalStatus.Up) .Select(networkInterface => DeviceLocator.DiscoverAsync(networkInterface, deviceFoundReporter: null)).ToList(); Dictionary <string, Device> allUniqueDevices = new Dictionary <string, Device>(); while (tasks.Count != 0) { Task <IEnumerable <Device> > completedTask = await Task.WhenAny(tasks); tasks.Remove(completedTask); IEnumerable <Device> devices = await completedTask; foreach (Device device in devices) { if (!allUniqueDevices.ContainsKey(device.Hostname)) { allUniqueDevices.Add(device.Hostname, device); yield return(device); } } if (cancel.HasValue && cancel.Value.IsCancellationRequested) { break; } } }
private static IEnumerable <Device> CheckSocketForDevices(IEnumerable <MulticastIPAddressInformation> multicastIPAddresses, UnicastIPAddressInformation ip, IProgress <Device> deviceFoundCallback, int retryCount) { // Use hash table for faster lookup, than List.Contains var devices = new Dictionary <string, Device>(); for (int count = 0; count < retryCount; count++) { foreach (MulticastIPAddressInformation mca in multicastIPAddresses) { try { using (var ssdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { var multicastIPEndpoint = new IPEndPoint(mca.Address, 1982); DeviceLocator.InitializeSocket(multicastIPEndpoint, ip, ssdpSocket); DeviceLocator.GetDevicesFromSocket(multicastIPEndpoint, deviceFoundCallback, ssdpSocket, devices); } } catch (SocketException ex) { //return devices.Values.ToList(); } } } return(devices.Values.ToList()); }
public static async Task <List <Device> > Discover(NetworkInterface preferredInterface) { List <Task <List <Device> > > tasks = DeviceLocator.CreateDiscoverTasks(preferredInterface, DeviceLocator.MaxRetryCount); List <Device>[] result = await Task.WhenAll(tasks); return(result .SelectMany(devices => devices) .GroupBy(d => d.Hostname) .Select(g => g.First()) .ToList()); }
private static void GetDevicesFromSocket(IPEndPoint multicastIPEndpoint, IProgress <Device> deviceFoundCallback, Socket ssdpSocket, Dictionary <string, Device> devices) { ssdpSocket.SendTo( Encoding.ASCII.GetBytes(string.Format(DeviceLocator._ssdpMessage, multicastIPEndpoint.Address)), SocketFlags.None, multicastIPEndpoint ); var stopWatch = Stopwatch.StartNew(); try { while (stopWatch.Elapsed < TimeSpan.FromSeconds(1)) { try // Catch socket read exception { int available = ssdpSocket.Available; if (available > 0) { var buffer = new byte[available]; int numberOfBytesRead = ssdpSocket.Receive(buffer, SocketFlags.None); if (numberOfBytesRead > 0) { string response = Encoding.UTF8.GetString(buffer.Take(numberOfBytesRead).ToArray()); Device device = DeviceLocator.GetDeviceInformationFromSsdpMessage(response); if (!devices.ContainsKey(device.Hostname)) { devices.Add(device.Hostname, device); deviceFoundCallback?.Report(device); } } } } catch (SocketException) { // Ignore SocketException and continue polling } Thread.Sleep(TimeSpan.FromMilliseconds(10)); } } finally { stopWatch.Stop(); } }
/// <summary> /// Create Discovery tasks for a specific Network Interface /// </summary> /// <param name="netInterface"></param> /// <param name="deviceFoundCallback"></param> /// <returns></returns> private static async Task <IEnumerable <Device> > SearchNetworkForDevicesAsync(NetworkInterface netInterface, IProgress <Device> deviceFoundCallback) { if (netInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || netInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet) { int retryCount = DeviceLocator.MaxRetryCount; IEnumerable <MulticastIPAddressInformation> multicastAddresses = DeviceLocator.GetMulticastIPAddressesForDiscovery(netInterface.GetIPProperties().MulticastAddresses); return(await Task.Run( () => netInterface.GetIPProperties().UnicastAddresses .Where(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) .AsParallel() .WithExecutionMode(ParallelExecutionMode.ForceParallelism) .SelectMany(ip => DeviceLocator.CheckSocketForDevices(multicastAddresses, ip, deviceFoundCallback, retryCount)) .ToList())); } return(new List <Device>()); }
public static async Task <List <Device> > Discover() { var tasks = new List <Task <List <Device> > >(); int retryCount = DeviceLocator.MaxRetryCount; foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up)) { tasks.AddRange(DeviceLocator.CreateDiscoverTasks(ni, retryCount)); } List <Device>[] result = await Task.WhenAll(tasks); return(result .SelectMany(devices => devices) .GroupBy(d => d.Hostname) .Select(g => g.First()) .ToList()); }
/// <summary> /// Discover devices in a specific Network Interface /// </summary> /// <param name="networkInterface"></param> /// <param name="deviceFoundReporter"></param> /// <returns></returns> public static async Task <IEnumerable <Device> > DiscoverAsync( NetworkInterface networkInterface, IProgress <Device> deviceFoundReporter) => await DeviceLocator.SearchNetworkForDevicesAsync(networkInterface, deviceFoundReporter);
/// <summary> /// Discover devices in a specific Network Interface /// </summary> /// <param name="networkInterface"></param> /// <returns></returns> public static async Task <IEnumerable <Device> > DiscoverAsync(NetworkInterface networkInterface) => await DeviceLocator.DiscoverAsync(networkInterface, null);
/// <summary> /// Discover devices in LAN /// </summary> /// <returns></returns> public static async Task <IEnumerable <Device> > DiscoverAsync(IProgress <Device> deviceFoundReporter) { IEnumerable <Task <IEnumerable <Device> > > tasks = NetworkInterface.GetAllNetworkInterfaces() .Where(networkInterface => networkInterface.OperationalStatus == OperationalStatus.Up) .Select(networkInterface => DeviceLocator.DiscoverAsync(networkInterface, deviceFoundReporter)); IEnumerable <Device>[] result = await Task.WhenAll(tasks); return(result .SelectMany(devices => devices) .GroupBy(d => d.Hostname) .Select(g => g.First()) .ToList()); }
/// <summary> /// Discover devices in LAN /// </summary> /// <returns></returns> public static async Task <IEnumerable <Device> > DiscoverAsync() => await DeviceLocator.DiscoverAsync(deviceFoundReporter : null);
private static List <Task <List <Device> > > CreateDiscoverTasks(NetworkInterface netInterface, int retryCount) { var devices = new ConcurrentDictionary <string, Device>(); var tasks = new List <Task <List <Device> > >(); if (netInterface.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 && netInterface.NetworkInterfaceType != NetworkInterfaceType.Ethernet) { return(tasks); } foreach (UnicastIPAddressInformation ip in netInterface.GetIPProperties().UnicastAddresses) { if (ip.Address.AddressFamily != AddressFamily.InterNetwork) { continue; } for (var count = 0; count < retryCount; count++) { Task <List <Device> > t = Task.Run( async() => { var stopWatch = new Stopwatch(); try { using (var ssdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) { Blocking = false, Ttl = 1, UseOnlyOverlappedIO = true, MulticastLoopback = false }) { ssdpSocket.Bind(new IPEndPoint(ip.Address, 0)); ssdpSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(DeviceLocator._multicastEndPoint.Address)); ssdpSocket.SendTo( DeviceLocator._ssdpDiagram, SocketFlags.None, DeviceLocator._multicastEndPoint); stopWatch.Start(); while (stopWatch.Elapsed < TimeSpan.FromSeconds(1)) { try { int available = ssdpSocket.Available; if (available > 0) { var buffer = new byte[available]; int i = ssdpSocket.Receive(buffer, SocketFlags.None); if (i > 0) { string response = Encoding.UTF8.GetString(buffer.Take(i).ToArray()); Device device = DeviceLocator.GetDeviceInformationFromSsdpMessage(response); //add only if no device already matching if (devices.TryAdd(device.Hostname, device)) { DeviceLocator.OnDeviceFound?.Invoke(null, new DeviceFoundEventArgs(device)); } } } } catch (SocketException) { // Continue polling } await Task.Delay(TimeSpan.FromMilliseconds(10)); } stopWatch.Stop(); } } catch (SocketException) { return(devices.Values.ToList()); } finally { stopWatch.Stop(); } return(devices.Values.ToList()); }); tasks.Add(t); } } return(tasks); }