private void Search(UdpClient client) { nextSearch = DateTime.Now.AddSeconds(SearchPeriod); byte[] data = DiscoverDeviceMessage.Encode(); // UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2) for (int i = 0; i < 3; i++) { client.Send(data, data.Length, searchEndpoint); } }
private static void CreateSocketsAndAddGateways() { sockets = new List <UdpClient> (); gatewayLists = new Dictionary <UdpClient, List <IPEndPoint> > (); try { foreach (NetworkInterface n in NetworkInterface.GetAllNetworkInterfaces()) { IPInterfaceProperties properties = n.GetIPProperties(); List <IPEndPoint> gatewayList = new List <IPEndPoint> (); foreach (GatewayIPAddressInformation gateway in properties.GatewayAddresses) { if (gateway.Address.AddressFamily == AddressFamily.InterNetwork) { gatewayList.Add(new IPEndPoint(gateway.Address, PmpConstants.ServerPort)); } } if (gatewayList.Count > 0) { foreach (UnicastIPAddressInformation address in properties.UnicastAddresses) { if (address.Address.AddressFamily == AddressFamily.InterNetwork) { UdpClient client; try { client = new UdpClient(new IPEndPoint(address.Address, 0)); } catch (SocketException) { continue; // Move on to the next address. } gatewayLists.Add(client, gatewayList); sockets.Add(client); } } } } } catch (Exception) { // NAT-PMP does not use multicast, so there isn't really a good fallback. } }
private void Search(UdpClient client) { // Sort out the time for the next search first. The spec says the // timeout should double after each attempt. Once it reaches 64 seconds // (and that attempt fails), assume no devices available nextSearch = DateTime.Now.AddMilliseconds(timeout); timeout *= 2; // We've tried 9 times as per spec, try searching again in 5 minutes if (timeout == 128 * 1000) { timeout = 250; nextSearch = DateTime.Now.AddMinutes(10); return; } // The nat-pmp search message. Must be sent to GatewayIP:53531 byte[] buffer = new byte[] { PmpConstants.Version, PmpConstants.OperationCode }; foreach (IPEndPoint gatewayEndpoint in gatewayLists[client]) { client.Send(buffer, buffer.Length, gatewayEndpoint); } }