private void SendMessage(PeerId id, PeerMessage message, MessagingCallback callback) { try { id.MessageSentCallback = callback; id.CurrentlySendingMessage = message; RateLimiterGroup limiter = id.TorrentManager.UploadLimiter; if (message is PieceMessage) { PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, limiter, id.Monitor, id.TorrentManager.Monitor, endSendMessageCallback, id); ClientEngine.BufferManager.FreeBuffer(ref ((PieceMessage)message).Data); id.IsRequestingPiecesCount--; } else { PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, null, id.Monitor, id.TorrentManager.Monitor, endSendMessageCallback, id); } } catch (Exception ex) { CleanupSocket(id, ex.Message); } }
public async Task SendData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); await NetworkIO.SendAsync(Incoming, new byte[oneMegabyte], 0, oneMegabyte, limiter, null, null); Assert.AreEqual(1, Incoming.Sends.Count, "#1"); }
public async Task SendData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); using var releaser = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> buffer); await NetworkIO.SendAsync(Incoming, buffer, limiter, null, null); Assert.AreEqual(1, Incoming.Sends.Count, "#1"); }
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); }
public async Task ReceiveData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); await Outgoing.SendAsync(new ByteBuffer (oneMegabyte), 0, oneMegabyte); await NetworkIO.ReceiveAsync(Incoming, new ByteBuffer (oneMegabyte), 0, oneMegabyte, limiter, null, null); Assert.AreEqual(1, Incoming.Receives.Count, "#1"); }
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); }
void CreateRateLimiters() { RateLimiter downloader = new RateLimiter(); downloadLimiter = new RateLimiterGroup(); downloadLimiter.Add(new PauseLimiter(this)); downloadLimiter.Add(downloader); RateLimiter uploader = new RateLimiter(); uploadLimiter = new RateLimiterGroup(); uploadLimiter.Add(new PauseLimiter(this)); uploadLimiter.Add(uploader); }
void CreateRateLimiters() { DownloadLimiter = new RateLimiter(); DownloadLimiters = new RateLimiterGroup { new PauseLimiter(this), DownloadLimiter }; UploadLimiter = new RateLimiter(); UploadLimiters = new RateLimiterGroup { new PauseLimiter(this), UploadLimiter }; }
public async Task ReceiveData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); using var r1 = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> sendBuffer); using var r2 = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> receiveBuffer); await Outgoing.SendAsync(sendBuffer); await NetworkIO.ReceiveAsync(Incoming, receiveBuffer, limiter, null, null); Assert.AreEqual(1, Incoming.Receives.Count, "#1"); }
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)); } }
void CreateRateLimiters() { RateLimiter downloader = new RateLimiter(); downloadLimiter = new RateLimiterGroup(); downloadLimiter.Add(new DiskWriterLimiter(DiskManager)); downloadLimiter.Add(downloader); RateLimiter uploader = new RateLimiter(); uploadLimiter = new RateLimiterGroup(); uploadLimiter.Add(uploader); MainLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate { downloader.UpdateChunks(Settings.GlobalMaxDownloadSpeed, TotalDownloadSpeed); uploader.UpdateChunks(Settings.GlobalMaxUploadSpeed, TotalUploadSpeed); return(!Disposed); }); }
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)); } }
void CreateRateLimiters() { RateLimiter downloader = new RateLimiter(); downloadLimiter = new RateLimiterGroup(); downloadLimiter.Add(new DiskWriterLimiter(DiskManager)); downloadLimiter.Add(downloader); RateLimiter uploader = new RateLimiter(); uploadLimiter = new RateLimiterGroup(); downloadLimiter.Add(new DiskWriterLimiter(DiskManager)); uploadLimiter.Add(uploader); ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate { downloader.UpdateChunks(Settings.GlobalMaxDownloadSpeed, TotalDownloadSpeed); uploader.UpdateChunks(Settings.GlobalMaxUploadSpeed, TotalUploadSpeed); return !disposed; }); }
internal async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id) { await MainLoop.SwitchToThreadpool(); ByteBufferPool.Releaser releaser = default; try { while (true) { if (id.AmRequestingPiecesCount == 0 && releaser.Buffer != null) { releaser.Dispose(); releaser = NetworkIO.BufferPool.Rent(1, out ByteBuffer _); } else if (id.AmRequestingPiecesCount > 0 && releaser.Buffer == null) { releaser.Dispose(); releaser = NetworkIO.BufferPool.Rent(Piece.BlockSize, out ByteBuffer _); } PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, releaser.Buffer).ConfigureAwait(false); HandleReceivedMessage(id, torrentManager, message); } } catch { releaser.Dispose(); await ClientEngine.MainLoop; CleanupSocket(torrentManager, id); } }
async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id) { try { while (true) { var message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager); if (id.Disposed) { if (message is PieceMessage msg) { ClientEngine.BufferManager.FreeBuffer(msg.Data); } } else { id.LastMessageReceived.Restart(); if (PeerMessageTransferred != null) { RaisePeerMessageTransferred(new PeerMessageEventArgs(id.TorrentManager, message, Direction.Incoming, id)); } message.Handle(id); } } } catch { CleanupSocket(id, "Could not receive a message"); } }
internal async void ReceiveMessagesAsync(IPeerConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id) { await MainLoop.SwitchToThreadpool(); Memory <byte> currentBuffer = default; Memory <byte> smallBuffer = default; ByteBufferPool.Releaser smallReleaser = default; Memory <byte> largeBuffer = default; ByteBufferPool.Releaser largeReleaser = default; try { while (true) { if (id.AmRequestingPiecesCount == 0) { if (!largeBuffer.IsEmpty) { largeReleaser.Dispose(); largeReleaser = default; largeBuffer = currentBuffer = default; } if (smallBuffer.IsEmpty) { smallReleaser = NetworkIO.BufferPool.Rent(ByteBufferPool.SmallMessageBufferSize, out smallBuffer); currentBuffer = smallBuffer; } } else { if (!smallBuffer.IsEmpty) { smallReleaser.Dispose(); smallReleaser = default; smallBuffer = currentBuffer = default; } if (largeBuffer.IsEmpty) { largeReleaser = NetworkIO.BufferPool.Rent(ByteBufferPool.LargeMessageBufferSize, out largeBuffer); currentBuffer = largeBuffer; } } (PeerMessage message, PeerMessage.Releaser releaser) = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, currentBuffer).ConfigureAwait(false); HandleReceivedMessage(id, torrentManager, message, releaser); } } catch { await ClientEngine.MainLoop; CleanupSocket(torrentManager, id); } finally { smallReleaser.Dispose(); largeReleaser.Dispose(); } }
async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id) { try { while (true) { var message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager); if (id.Disposed) { if (message is PieceMessage msg) { ClientEngine.BufferManager.FreeBuffer(msg.Data); } } else { id.LastMessageReceived.Restart(); message.Handle(torrentManager, id); } } } catch { CleanupSocket(torrentManager, id); } }
internal async void ReceiveMessagesAsync(IConnection2 connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id) { try { while (true) { Messages.PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager.Torrent); if (id.Disposed) { if (message is PieceMessage msg) { msg.DataReleaser.Dispose(); } break; } else { id.LastMessageReceived.Restart(); torrentManager.Mode.HandleMessage(id, message); } } } catch { CleanupSocket(torrentManager, id); } }