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(); } }
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); }