Esempio n. 1
0
        public void UdpBroadcastSettings_Server()
        {
            try
            {
                UdpBroadcastServerSettings settings;

                // Verify that we can read reasonable settings.

                var cfg1 = @"
&section Settings
    NetworkBinding           = 1.1.1.1:10
    SocketBufferSize         = 128K
    Server[0]                = 1.1.1.1:10
    Server[1]                = 2.2.2.2:20
    SharedKey                = aes:NtSkj76eyCAsJE4TnTqmPOuKd5hDDWwSS7ccTfeKEL8=:S9Xc6skGFWtxoxBaoTxJlQ==
    MessageTTL               = 15m
    BkTaskInterval           = 7s
    ClusterKeepAliveInterval = 10s
    ServerTTL                = 15s
    ClientTTL                = 20s
&endsection
";
                Config.SetConfig(cfg1.Replace('&', '#'));

                settings = new UdpBroadcastServerSettings("Settings");
                Assert.AreEqual(new NetworkBinding("1.1.1.1:10"), 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(TimeSpan.FromSeconds(7), settings.BkTaskInterval);
                Assert.AreEqual(TimeSpan.FromSeconds(10), settings.ClusterKeepAliveInterval);
                Assert.AreEqual(TimeSpan.FromSeconds(15), settings.ServerTTL);
                Assert.AreEqual(TimeSpan.FromSeconds(20), settings.ClientTTL);

                // Verify that an exception is thrown if no servers are specified.

                Config.SetConfig(string.Empty);

                try
                {
                    settings = new UdpBroadcastServerSettings("Settings");
                }
                catch (Exception e)
                {
                    Assert.IsInstanceOfType(e, typeof(FormatException));
                }
            }
            finally
            {
                Config.SetConfig(null);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Creates and starts a UDP broadcast server using the settings passed.
        /// </summary>
        /// <param name="settings">The server settings.</param>
        /// <param name="perfCounters">The application's performance counters (or <c>null</c>).</param>
        /// <param name="perfPrefix">The string to prefix any performance counter names (or <c>null</c>).</param>
        /// <remarks>
        /// <note>
        /// The <paramref name="perfCounters" /> parameter is type as <see cref="object" /> so that
        /// applications using this class will not be required to reference the <b>LillTel.Advanced</b>
        /// assembly.
        /// </note>
        /// </remarks>
        /// <exception cref="ArgumentException">Thrown if the settings passed are not valid.</exception>
        public UdpBroadcastServer(UdpBroadcastServerSettings settings, object perfCounters, string perfPrefix)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            if (settings.Servers == null || settings.Servers.Length == 0)
            {
                throw new ArgumentException("Invalid UDP broadcast server settings: At least one broadcast server endpoint is required.");
            }

            if (perfCounters != null && !(perfCounters is PerfCounterSet))
            {
                throw new ArgumentException("Only instances of type [PerfCounterSet] may be passed in the [perfCounters] parameter.", "perfCounters");
            }

            this.startTime    = DateTime.UtcNow;
            this.closePending = false;
            this.settings     = settings;
            this.perf         = new Perf(perfCounters as PerfCounterSet, perfPrefix);

            bool found = false;

            for (int i = 0; i < settings.Servers.Length; i++)
            {
                var binding = settings.Servers[i];

                if (binding == settings.NetworkBinding)
                {
                    found = true;

                    // I'm going to special case the situation where the network binding address is ANY.
                    // In this case, one of the server endpoints must also include an ANY entry and I'll
                    // fill out with the loop back addres (127.1.0.1).

                    if (binding.IsAnyAddress)
                    {
                        settings.Servers[i] = new NetworkBinding(IPAddress.Loopback, settings.Servers[i].Port);
                    }

                    break;
                }
            }

            if (!found)
            {
                if (!settings.NetworkBinding.IsAnyAddress)
                {
                    throw new ArgumentException("Invalid UDP broadcast server settings: The current server's network binding must also be present in the Servers[] bindings.");
                }
            }

            // Initialize the clients and servers state.

            clients = new Dictionary <IPEndPoint, ClientState>();
            servers = new Dictionary <IPEndPoint, ServerState>();

            // 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[TcpConst.MTU];

            rawRecvEP = new IPEndPoint(IPAddress.Any, 0);
            socket.BeginReceiveFrom(recvBuf, 0, recvBuf.Length, SocketFlags.None, ref rawRecvEP, onReceive, null);

            // Crank up a timer to send the ClientRegister messages to the server cluster.

            registerTimer = new PolledTimer(settings.ClusterKeepAliveInterval, true);
            registerTimer.FireNow();    // Make sure that we send registration messages immediately

            bkTimer = new GatedTimer(new TimerCallback(OnBkTask), null, TimeSpan.Zero, settings.BkTaskInterval);
        }