예제 #1
0
        static void Main(string[] args)
        {
            var simulator = new Simulator() { MaxNetworkSpeed = 5 << 10, SimulationInterval = 500 };

            // initialize two devices and register them to the network
            var d1 = new Device() { Name = "D1" };
            var d2 = new Device() { Name = "D2" };
            simulator.Register(d1, null);
            simulator.Register(d2, new int[] { d1.ID });

            // define their responses to the received data.
            var defaultReceivedHandler = new EventHandler<DataReceivedEventArgs>((sender, e) =>
            {
                var device = sender as Device;
                Console.WriteLine("Data received from {0} to {1}.", e.SourceDevice.Name, device.Name);
            });
            d1.DataReceived += defaultReceivedHandler;
            d2.DataReceived += defaultReceivedHandler;

            // test send a large bulk of data
            d1.Send(d2, new byte[20 << 10], true, () => { Console.WriteLine("Data sent complete from D1 to D2"); });
            Console.WriteLine("Block point reached.");

            // perform another round
            var d3 = new Device { Name = "D3" };
            simulator.Register(d3, new int[] { d1.ID, d2.ID });
            d3.DataReceived += defaultReceivedHandler;
            d3.Send(d2, new byte[20 << 10], false, () => { Console.WriteLine("Data sent complete from D3 to D2"); });
            d3.Send(d1, new byte[20 << 10], true, () => { Console.WriteLine("Data sent complete from D3 to D1"); });

            // d1 leaves the network, and then try to send it some data
            simulator.Leave(d1);
            try
            {
                d3.Send(d1, new byte[10]);
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Error: " + e.Message);
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            Application.Run();
        }
예제 #2
0
 /// <summary>
 /// Sends the specified data to the target device.
 /// </summary>
 /// <param name="target">The target device.</param>
 /// <param name="data">The data.</param>
 /// <param name="callback">The callback which will be invoked when data sending is finished.</param>
 public void Send(Device target, byte[] data, bool isBlocked = false, Action callback = null)
 {
     if (isBlocked)
     {
         var e = new AutoResetEvent(false);
         Simulator.Send(this, target, data, () => { if (callback != null) callback(); e.Set(); }, TriggerDataReceivedEvent);
         e.WaitOne();
     }
     else
     {
         Simulator.Send(this, target, data, callback, TriggerDataReceivedEvent);
     }
 }
예제 #3
0
 /// <summary>
 /// Registers the specified device in the network.
 /// </summary>
 /// <param name="d">The d.</param>
 /// <param name="connectedIds">The connected ids.</param>
 /// <returns>Assigned ID to the device</returns>
 public void Register(Device d, int[] connectedIds)
 {
     devices.Add(d);
     activeIds.Add(nextId);
     d.ID = nextId;
     d.Simulator = this;
     AdjacentList.Add(nextId, new List<int>());
     if (connectedIds != null)
         foreach (var id in connectedIds)
             Connect(nextId, id);
     ++nextId;
 }
예제 #4
0
        /// <summary>
        /// Sends the specified data from a device to another.
        /// </summary>
        /// <param name="from">The device from which the data is sent.</param>
        /// <param name="to">The target device</param>
        /// <param name="data">The data.</param>
        /// <remarks>
        /// This function also force the network speed limit. Currently the limit is put
        /// in the capability of receiving data for every device.
        /// </remarks>
        public void Send(Device from, Device to, byte[] data, Action callback, EventHandler<DataReceivedEventArgs> dataReceivedTrigger)
        {
            // check whether the two devices are connected.
            if (!AdjacentList[from.ID].Contains(to.ID))
                throw new Exception("The two devices are not connected.");

            // prepare for the buffer,callback queue, and sourceDevice queue
            if (!dataToSend.ContainsKey(to.ID))
                dataToSend.Add(to.ID, new Queue<Queue<byte>>());
            dataToSend[to.ID].Enqueue(new Queue<byte>(data));
            if (!callbacks.ContainsKey(to.ID))
                callbacks.Add(to.ID, new Queue<Action>());
            callbacks[to.ID].Enqueue(callback);
            if (!sourceDevices.ContainsKey(to.ID))
                sourceDevices.Add(to.ID, new Queue<Device>());
            sourceDevices[to.ID].Enqueue(from);

            // Set a time to trigger the data received events.
            if (sendingIds.Contains(to.ID)) return;
            sendingIds.Add(to.ID);
            var timer = new System.Timers.Timer(this.SimulationInterval) { AutoReset = true };
            timer.Elapsed += (sender, e) =>
            {
                // use closure to access the target device
                var queue = dataToSend[to.ID].Peek();
                var buffer = new byte[Math.Min(this.MaxNetworkSpeed, queue.Count)];
                for (int i = 0; i < buffer.Length; i++)
                    buffer[i] = queue.Dequeue();
                // trigger the event
                var sourceDevice = sourceDevices[to.ID].Peek();
                dataReceivedTrigger(to, new DataReceivedEventArgs() { SourceDevice = sourceDevice, Data = buffer });
                // dispose the timer when all the data is sent.
                if (queue.Count == 0)
                {
                    if (dataToSend[to.ID].Count == 0)
                    {
                        timer.Dispose();
                        sendingIds.Remove(to.ID);
                    }
                    sourceDevices[to.ID].Dequeue();
                    var toCallBack = callbacks[to.ID].Dequeue();
                    if (toCallBack != null) toCallBack();
                    dataToSend[to.ID].Dequeue();
                }
            };
            timer.Enabled = true;
        }
예제 #5
0
 /// <summary>
 /// Make specified device leave the network.
 /// </summary>
 /// <param name="d">The d.</param>
 public void Leave(Device d)
 {
     devices.Remove(d);
     activeIds.Remove(d.ID);
     AdjacentList.Remove(d.ID);  //Directly disconnect all the neighbors.
     // note the connections are symmetric. Do another round.
     foreach (var key in AdjacentList.Keys)
         if (AdjacentList[key].Contains(d.ID))
             AdjacentList[key].Remove(d.ID);
 }