public void UdpBroadcastSettings_Client() { try { UdpBroadcastClientSettings settings; // Verify that we can read reasonable settings. var cfg1 = @" §ion Settings NetworkBinding = 3.3.3.3:30 SocketBufferSize = 128K Server[0] = 1.1.1.1:10 Server[1] = 2.2.2.2:20 SharedKey = aes:NtSkj76eyCAsJE4TnTqmPOuKd5hDDWwSS7ccTfeKEL8=:S9Xc6skGFWtxoxBaoTxJlQ== MessageTTL = 15m BroadcastGroup = 99 BkTaskInterval = 15s KeepAliveInterval = 10s ServerResolveInterval = 20s &endsection "; Config.SetConfig(cfg1.Replace('&', '#')); settings = new UdpBroadcastClientSettings("Settings"); Assert.AreEqual(new NetworkBinding("3.3.3.3:30"), settings.NetworkBinding); Assert.AreEqual(128 * 1024, settings.SocketBufferSize); CollectionAssert.AreEqual(new NetworkBinding[] { new NetworkBinding("1.1.1.1:10"), new NetworkBinding("2.2.2.2:20") }, settings.Servers); Assert.AreEqual(99, settings.BroadcastGroup); Assert.AreEqual(TimeSpan.FromSeconds(15), settings.BkTaskInterval); Assert.AreEqual(TimeSpan.FromSeconds(10), settings.KeepAliveInterval); Assert.AreEqual(TimeSpan.FromSeconds(20), settings.ServerResolveInterval); // Verify that an exception is thrown if no servers are specified. Config.SetConfig(string.Empty); try { settings = new UdpBroadcastClientSettings("Settings"); } catch (Exception e) { Assert.IsInstanceOfType(e, typeof(FormatException)); } } finally { Config.SetConfig(null); } }
/// <summary> /// Creates and starts a UDP broadcast client using the settings passed. /// </summary> /// <param name="settings">The client settings.</param> /// <exception cref="ArgumentException">Thrown if the settings passed are not valid.</exception> public UdpBroadcastClient(UdpBroadcastClientSettings settings) { this.settings = settings; if (settings == null) { throw new ArgumentNullException("settings"); } if (settings.Servers == null || settings.Servers.Length == 0) { throw new ArgumentException("Invalid UDP broadcast client settings: At least one broadcast server endpoint is required."); } this.servers = new List <IPEndPoint>(); // $hack(jeff.lill) // // This is a bit of a hack to discover the source IP address to use for this instance. // If the configured NetworkBinding specifies a specific interface, then we'll use // this, otherwise we'll use the IPv4 address for the first active network adaptor we find. // In a perfect world, I'd send a packet to the broadcast servers and have it respond with // the UDP source address it sees that would discover the actual IP address. This hack // should work 99% of the time though. if (!settings.NetworkBinding.Address.Equals(IPAddress.Any)) { this.sourceAddress = settings.NetworkBinding.Address; } else { this.sourceAddress = NetHelper.GetActiveAdapter(); } // Open the socket and start receiving packets. socket = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.IgnoreUdpConnectionReset = true; socket.ReceiveBufferSize = settings.SocketBufferSize; socket.SendBufferSize = settings.SocketBufferSize; socket.Bind(settings.NetworkBinding); onReceive = new AsyncCallback(OnReceive); recvBuf = new byte[8192]; rawRecvEP = new IPEndPoint(IPAddress.Any, 0); socket.BeginReceiveFrom(recvBuf, 0, recvBuf.Length, SocketFlags.None, ref rawRecvEP, onReceive, null); // Crank up the timers. keepAliveTimer = new PolledTimer(settings.KeepAliveInterval, false); keepAliveTimer.FireNow(); serverResolveTimer = new PolledTimer(settings.ServerResolveInterval, false); serverResolveTimer.FireNow(); bkTimer = new GatedTimer(new TimerCallback(OnBkTask), null, TimeSpan.Zero, settings.BkTaskInterval); // Sleep for a couple seconds to allow the server DNS lookups to complete. Thread.Sleep(2000); }