예제 #1
0
        public ClientEngine(EngineSettings settings, PeerListener listener, PieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            this.Listener = listener;
            this.Settings = settings;

            this.ConnectionManager = new ConnectionManager(this);
            RegisterDht(new NullDhtEngine());
            this.DiskManager   = new DiskManager(this, writer);
            this.listenManager = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });
            this.torrents         = new List <TorrentManager>();
            this.torrentsReadonly = new ReadOnlyCollection <TorrentManager> (torrents);
            CreateRateLimiters();
            this.PeerId = GeneratePeerId();

            localPeerListener      = new LocalPeerListener(this);
            localPeerManager       = new LocalPeerManager();
            LocalPeerSearchEnabled = SupportsLocalPeerDiscovery;
            listenManager.Register(listener);
            // This means we created the listener in the constructor
            if (listener.Endpoint.Port == 0)
            {
                listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort));
            }
        }
예제 #2
0
        static NetworkIO()
        {
            IOLoop.QueueTimeout(TimeSpan.FromMilliseconds(100), delegate {
                while (receiveQueue.Count > 0)
                {
                    var io = receiveQueue.Peek();
                    if (io.rateLimiter.TryProcess(io.count))
                    {
                        ReceiveQueuedAsync(receiveQueue.Dequeue());
                    }
                    else
                    {
                        break;
                    }
                }
                while (sendQueue.Count > 0)
                {
                    var io = sendQueue.Peek();
                    if (io.rateLimiter.TryProcess(io.count))
                    {
                        SendQueuedAsync(sendQueue.Dequeue());
                    }
                    else
                    {
                        break;
                    }
                }

                return(true);
            });
        }
예제 #3
0
        public void RepeatedTask()
        {
            //Console.WriteLine("Starting");
            ManualResetEvent handle = new ManualResetEvent(false);

            loop.QueueTimeout(TimeSpan.FromMilliseconds(0), delegate {
                this.count++;
                if (count == 3)
                {
                    handle.Set();
                    return(false);
                }

                return(true);
            });
            Assert.IsTrue(handle.WaitOne(5000, true), "#1: Executed {0} times", count);
            Assert.AreEqual(3, count, "#2");
        }
        public ClientEngine (EngineSettings settings, Factories factories)
        {
            settings = settings ?? throw new ArgumentNullException (nameof (settings));
            Factories = factories ?? throw new ArgumentNullException (nameof (factories));

            // This is just a sanity check to make sure the ReusableTasks.dll assembly is
            // loadable.
            GC.KeepAlive (ReusableTasks.ReusableTask.CompletedTask);

            PeerId = GeneratePeerId ();
            Settings = settings ?? throw new ArgumentNullException (nameof (settings));
            CheckSettingsAreValid (Settings);

            allTorrents = new List<TorrentManager> ();
            dhtNodeLocker = new SemaphoreSlim (1, 1);
            publicTorrents = new List<TorrentManager> ();
            Torrents = new ReadOnlyCollection<TorrentManager> (publicTorrents);

            DiskManager = new DiskManager (Settings, Factories);

            ConnectionManager = new ConnectionManager (PeerId, Settings, Factories, DiskManager);
            listenManager = new ListenManager (this);
            PortForwarder = Factories.CreatePortForwarder ();

            MainLoop.QueueTimeout (TimeSpan.FromMilliseconds (TickLength), delegate {
                if (IsRunning && !Disposed)
                    LogicTick ();
                return !Disposed;
            });

            downloadLimiter = new RateLimiter ();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter = new RateLimiter ();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            PeerListener = (settings.ListenEndPoint == null ? null : Factories.CreatePeerConnectionListener (settings.ListenEndPoint)) ?? new NullPeerListener ();
            listenManager.SetListener (PeerListener);

            DhtListener = (settings.DhtEndPoint == null ? null : Factories.CreateDhtListener (settings.DhtEndPoint)) ?? new NullDhtListener ();
            DhtEngine = (settings.DhtEndPoint == null ? null : Factories.CreateDht ()) ?? new NullDhtEngine ();
            Dht = new DhtEngineWrapper (DhtEngine);
            DhtEngine.SetListenerAsync (DhtListener).GetAwaiter ().GetResult ();

            DhtEngine.StateChanged += DhtEngineStateChanged;
            DhtEngine.PeersFound += DhtEnginePeersFound;
            LocalPeerDiscovery = new NullLocalPeerDiscovery ();

            RegisterLocalPeerDiscovery (settings.AllowLocalPeerDiscovery ? Factories.CreateLocalPeerDiscovery () : null);
        }
예제 #5
0
        public ClientEngine(EngineSettings settings)
        {
            settings = settings ?? throw new ArgumentNullException(nameof(settings));

            // This is just a sanity check to make sure the ReusableTasks.dll assembly is
            // loadable.
            GC.KeepAlive(ReusableTasks.ReusableTask.CompletedTask);

            PeerId   = GeneratePeerId();
            Settings = settings ?? throw new ArgumentNullException(nameof(settings));
            CheckSettingsAreValid(Settings);

            allTorrents    = new List <TorrentManager> ();
            publicTorrents = new List <TorrentManager> ();
            Torrents       = new ReadOnlyCollection <TorrentManager> (publicTorrents);

            DiskManager = new DiskManager(Settings);
            DiskManager.ChangePieceWriter(new DiskWriter(Settings.MaximumOpenFiles));

            ConnectionManager = new ConnectionManager(PeerId, Settings, DiskManager);
            listenManager     = new ListenManager(this);
            PortForwarder     = new MonoNatPortForwarder();

            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });

            downloadLimiter  = new RateLimiter();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter  = new RateLimiter();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            Listener = PeerListenerFactory.CreateTcp(settings.ListenPort);
            listenManager.SetListener(Listener);

            DhtListener             = DhtListenerFactory.CreateUdp(settings.DhtPort);
            DhtEngine               = settings.DhtPort == -1 ? new NullDhtEngine() : DhtEngineFactory.Create(DhtListener);
            DhtEngine.StateChanged += DhtEngineStateChanged;
            DhtEngine.PeersFound   += DhtEnginePeersFound;

            RegisterLocalPeerDiscovery(settings.AllowLocalPeerDiscovery && settings.ListenPort > 0 ? LocalPeerDiscoveryFactory.Create(settings.ListenPort) : null);
        }
예제 #6
0
        public ClientEngine(EngineSettings settings, IPeerListener listener, IPieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            // This is just a sanity check to make sure the ReusableTasks.dll assembly is
            // loadable.
            GC.KeepAlive(ReusableTasks.ReusableTask.CompletedTask);

            PeerId   = GeneratePeerId();
            Listener = listener ?? throw new ArgumentNullException(nameof(listener));
            Settings = settings ?? throw new ArgumentNullException(nameof(settings));

            allTorrents    = new List <TorrentManager> ();
            publicTorrents = new List <TorrentManager> ();
            Torrents       = new ReadOnlyCollection <TorrentManager> (publicTorrents);

            DiskManager       = new DiskManager(Settings, writer);
            ConnectionManager = new ConnectionManager(PeerId, Settings, DiskManager);
            DhtEngine         = new NullDhtEngine();
            listenManager     = new ListenManager(this);
            PortForwarder     = new MonoNatPortForwarder();

            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });

            downloadLimiter  = new RateLimiter();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter  = new RateLimiter();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            listenManager.Register(listener);

            if (SupportsLocalPeerDiscovery)
            {
                RegisterLocalPeerDiscovery(new LocalPeerDiscovery(Settings));
            }
        }
예제 #7
0
        public ClientEngine(EngineSettings settings, IPeerListener listener, IPieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            PeerId   = GeneratePeerId();
            Listener = listener ?? throw new ArgumentNullException(nameof(listener));
            Settings = settings ?? throw new ArgumentNullException(nameof(settings));

            torrents = new List <TorrentManager>();
            Torrents = new ReadOnlyCollection <TorrentManager> (torrents);

            DiskManager       = new DiskManager(Settings, writer);
            ConnectionManager = new ConnectionManager(PeerId, Settings, DiskManager);
            DhtEngine         = new NullDhtEngine();
            listenManager     = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });

            downloadLimiter  = new RateLimiter();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter  = new RateLimiter();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            listenManager.Register(listener);

            if (SupportsLocalPeerDiscovery)
            {
                RegisterLocalPeerDiscovery(new LocalPeerDiscovery(Settings));
            }
        }
예제 #8
0
        internal DiskManager(ClientEngine engine, PieceWriter writer)
        {
            this.bufferedReads  = new Queue <BufferedIO>();
            this.bufferedWrites = new Queue <BufferedIO>();
            this.engine         = engine;
            this.ReadLimiter    = new RateLimiter();
            this.readMonitor    = new SpeedMonitor();
            this.writeMonitor   = new SpeedMonitor();
            this.WriteLimiter   = new RateLimiter();
            this.Writer         = writer;

            IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), () => {
                readMonitor.Tick();
                writeMonitor.Tick();

                WriteLimiter.UpdateChunks(engine.Settings.MaxWriteRate, WriteRate);
                ReadLimiter.UpdateChunks(engine.Settings.MaxReadRate, ReadRate);

                ProcessBufferedIO();

                return(!Disposed);
            });
        }
예제 #9
0
        public ClientEngine(EngineSettings settings, IPeerListener listener, PieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            this.Listener = listener;
            this.Settings = settings;

            this.ConnectionManager = new ConnectionManager(this);
            DhtEngine          = new NullDhtEngine();
            this.DiskManager   = new DiskManager(this, writer);
            this.listenManager = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });
            this.torrents         = new List <TorrentManager>();
            this.torrentsReadonly = new ReadOnlyCollection <TorrentManager> (torrents);
            downloadLimiter       = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                new RateLimiter()
            };

            uploadLimiter = new RateLimiter();
            this.PeerId   = GeneratePeerId();

            localPeerListener            = new LocalPeerListener();
            localPeerListener.PeerFound += HandleLocalPeerFound;
            localPeerManager             = new LocalPeerManager();
            LocalPeerSearchEnabled       = SupportsLocalPeerDiscovery;
            listenManager.Register(listener);
        }
예제 #10
0
        internal DiskManager(ClientEngine engine, PieceWriter writer)
        {
            this.bufferedReads  = new Queue <BufferedIO>();
            this.bufferedWrites = new Queue <BufferedIO>();
            this.cache          = new Cache <BufferedIO>(true).Synchronize();
            this.engine         = engine;
            this.readLimiter    = new RateLimiter();
            this.readMonitor    = new SpeedMonitor();
            this.writeMonitor   = new SpeedMonitor();
            this.writeLimiter   = new RateLimiter();
            this.writer         = writer;

            LoopTask = delegate {
                if (disposed)
                {
                    return;
                }

                while (this.bufferedWrites.Count > 0 && writeLimiter.TryProcess(bufferedWrites.Peek().buffer.Length / 2048))
                {
                    BufferedIO write;
                    lock (bufferLock)
                        write = this.bufferedWrites.Dequeue();
                    try
                    {
                        PerformWrite(write);
                        cache.Enqueue(write);
                    }
                    catch (Exception ex)
                    {
                        //if (write.Manager != null)
                        //    SetError(write.Manager, Reason.WriteFailure, ex);
                    }
                }

                while (this.bufferedReads.Count > 0 && readLimiter.TryProcess(bufferedReads.Peek().Count / 2048))
                {
                    BufferedIO read;
                    lock (bufferLock)
                        read = this.bufferedReads.Dequeue();

                    try
                    {
                        PerformRead(read);
                        cache.Enqueue(read);
                    }
                    catch (Exception ex)
                    {
                        if (read.Manager != null)
                        {
                            SetError(read.Manager, Reason.ReadFailure, ex);
                        }
                    }
                }
            };

            IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate {
                if (disposed)
                {
                    return(false);
                }

                readMonitor.Tick();
                writeMonitor.Tick();
                LoopTask();
                return(true);
            });
        }