public void Choke2() { PeerId other = rig.CreatePeer(true); // More peers than slots unchoker.PeerDisconnected(this.peer); rig.Manager.Settings.UploadSlots = 1; List <PeerId> peers = new List <PeerId>(new PeerId[] { this.peer, rig.CreatePeer(true), rig.CreatePeer(true) }); peers.ForEach(unchoker.PeerConnected); unchoker.UnchokeReview(); peers.ForEach(delegate(PeerId p) { p.IsInterested = true; }); unchoker.UnchokeReview(); Assert.IsFalse(peers[0].AmChoking); Assert.IsTrue(peers[1].AmChoking); Assert.IsTrue(peers[2].AmChoking); for (int current = 0; current < peers.Count; current++) { PeerId peer = peers[current]; Assert.IsFalse(peer.AmChoking); Queue <int> haves = new Queue <int>(); for (int i = 0; i < unchoker.MaxAdvertised; i++) { haves.Enqueue(((HaveMessage)peer.Dequeue()).PieceIndex); } Assert.IsInstanceOf(typeof(UnchokeMessage), peer.Dequeue()); while (haves.Count > 0) { unchoker.UnchokeReview(); Assert.IsFalse(peer.AmChoking); peers.ForEach(delegate(PeerId p) { if (p != peer) { Assert.IsTrue(p.AmChoking); } }); Assert.AreEqual(0, peer.QueueLength); unchoker.ReceivedHave(other, haves.Dequeue()); } unchoker.UnchokeReview(); Assert.IsTrue(peer.AmChoking); Assert.IsInstanceOf(typeof(ChokeMessage), peer.Dequeue()); } Assert.IsFalse(peers[0].AmChoking); Assert.IsTrue(peers[1].AmChoking); Assert.IsTrue(peers[2].AmChoking); peers.ForEach(delegate(PeerId p) { Assert.Less(0, p.QueueLength); }); }
/// <param name="id">The peer whose message queue you want to start processing</param> internal void ProcessQueue(PeerId id) { if (id.QueueLength == 0) { id.ProcessingQueue = false; return; } PeerMessage msg = id.Dequeue(); if (msg is PieceMessage) { using (ManualResetEvent handle = new ManualResetEvent(false)) { PieceMessage pm = (PieceMessage)msg; pm.Data = BufferManager.EmptyBuffer; ClientEngine.BufferManager.GetBuffer(ref pm.Data, pm.ByteLength); engine.DiskManager.QueueRead(id.TorrentManager, pm.StartOffset + ((long)pm.PieceIndex * id.TorrentManager.Torrent.PieceLength), pm.Data, pm.RequestLength, delegate { handle.Set(); }); handle.WaitOne(); id.PiecesSent++; } } try { SendMessage(id, msg, this.messageSentCallback); } catch (Exception e) { CleanupSocket(id, "Exception calling SendMessage: " + e.Message); } }
protected virtual void HandleCancelMessage(PeerId id, CancelMessage message) { PeerMessage msg; for (int i = 0; i < id.QueueLength; i++) { msg = id.Dequeue(); if (!(msg is PieceMessage)) { id.Enqueue(msg); continue; } PieceMessage piece = msg as PieceMessage; if (!(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) { id.Enqueue(msg); } else { id.IsRequestingPiecesCount--; } } for (int i = 0; i < id.PieceReads.Count; i++) { if (id.PieceReads[i].PieceIndex == message.PieceIndex && id.PieceReads[i].StartOffset == message.StartOffset && id.PieceReads[i].RequestLength == message.RequestLength) { id.IsRequestingPiecesCount--; id.PieceReads.RemoveAt(i); break; } } }
public void ChunkedRequest() { rig.Manager.PieceManager.Picker.CancelRequests(id); rig.Manager.PieceManager.AddPieceRequests(id); requests = (RequestBundle)id.Dequeue(); byte[] sendBuffer = requests.Encode(); var sendTask = Send(sendBuffer, 0, sendBuffer.Length, 1); Assert.ThrowsAsync <ArgumentException> (() => sendTask); }
/// <param name="id">The peer whose message queue you want to start processing</param> internal async void ProcessQueue(PeerId id) { while (id.QueueLength > 0) { try { PeerMessage msg = id.Dequeue(); var pm = msg as PieceMessage; if (pm != null) { pm.Data = ClientEngine.BufferManager.GetBuffer(pm.ByteLength); await engine.DiskManager.ReadAsync(id.TorrentManager, pm.StartOffset + ((long)pm.PieceIndex *id.TorrentManager.Torrent.PieceLength), pm.Data, pm.RequestLength); id.PiecesSent++; } await PeerIO.SendMessageAsync(id.Connection, id.Encryptor, msg, id.TorrentManager.UploadLimiter, id.Monitor, id.TorrentManager.Monitor); if (msg is PieceMessage) { id.IsRequestingPiecesCount--; } if (pm != null) { ClientEngine.BufferManager.FreeBuffer(pm.Data); } // Fire the event to let the user know a message was sent if (PeerMessageTransferred != null) { RaisePeerMessageTransferred(new PeerMessageEventArgs(id.TorrentManager, msg, Direction.Outgoing, id)); } id.LastMessageSent.Restart(); } catch (Exception e) { CleanupSocket(id, "Exception calling SendMessage: " + e.Message); break; } } id.ProcessingQueue = false; }
/// <summary> /// /// </summary> /// <param name="manager">The torrent which the peer is associated with.</param> /// <param name="id">The peer whose message queue you want to start processing</param> internal async void ProcessQueue(TorrentManager manager, PeerId id) { while (id.QueueLength > 0) { var msg = id.Dequeue(); var pm = msg as PieceMessage; try { if (pm != null) { pm.Data = ClientEngine.BufferManager.GetBuffer(pm.ByteLength); try { await DiskManager.ReadAsync(manager.Torrent, pm.StartOffset + ((long)pm.PieceIndex * manager.Torrent.PieceLength), pm.Data, pm.RequestLength); } catch (Exception ex) { manager.TrySetError(Reason.ReadFailure, ex); return; } id.PiecesSent++; } await PeerIO.SendMessageAsync(id.Connection, id.Encryptor, msg, manager.UploadLimiters, id.Monitor, manager.Monitor); if (msg is PieceMessage) { id.IsRequestingPiecesCount--; } id.LastMessageSent.Restart(); } catch { CleanupSocket(manager, id); break; } finally { if (pm?.Data != null) { ClientEngine.BufferManager.FreeBuffer(pm.Data); } } } id.ProcessingQueue = false; }
public void Setup() { requestedUrl.Clear(); partialData = false; rig = TestRig.CreateMultiFile(); rig.Manager.ChangePicker(new StandardPicker()); connection = new HttpConnection(new Uri(ListenerURL)); connection.Manager = rig.Manager; rig.Manager.UnhashedPieces.SetAll(false); id = new PeerId(new Peer("this is my id", connection.Uri), connection, rig.Manager.Bitfield?.Clone().SetAll(false)); id.IsChoking = false; id.AmInterested = true; id.BitField.SetAll(true); id.MaxPendingRequests = numberOfPieces; rig.Manager.PieceManager.AddPieceRequests(id); requests = (RequestBundle)id.Dequeue(); }
/// <summary> /// Checks the send queue of the peer to see if there are any outstanding pieces which they requested /// and rejects them as necessary /// </summary> /// <param name="Peer"></param> private void RejectPendingRequests(PeerId Peer) { PeerMessage message; PieceMessage pieceMessage; int length = Peer.QueueLength; for (int i = 0; i < length; i++) { message = Peer.Dequeue(); if (!(message is PieceMessage)) { Peer.Enqueue(message); continue; } pieceMessage = (PieceMessage)message; // If the peer doesn't support fast peer, then we will never requeue the message if (!(Peer.SupportsFastPeer && ClientEngine.SupportsFastPeer)) { Peer.IsRequestingPiecesCount--; continue; } // If the peer supports fast peer, queue the message if it is an AllowedFast piece // Otherwise send a reject message for the piece if (Peer.AmAllowedFastPieces.Contains(pieceMessage.PieceIndex)) { Peer.Enqueue(pieceMessage); } else { Peer.IsRequestingPiecesCount--; Peer.Enqueue(new RejectRequestMessage(pieceMessage)); } } }
public async Task SingleFileTorrent() { rig.Dispose(); rig = TestRig.CreateSingleFile(); rig.Torrent.GetRightHttpSeeds.Add($"{ListenerURL}File1.exe"); string url = rig.Torrent.GetRightHttpSeeds[0]; connection = new HttpConnection(new Uri(url)); connection.Manager = rig.Manager; rig.Manager.UnhashedPieces.SetAll(false); id = new PeerId(new Peer("this is my id", connection.Uri), id.Connection, rig.Manager.Bitfield?.Clone().SetAll(false)); id.IsChoking = false; id.AmInterested = true; id.BitField.SetAll(true); id.MaxPendingRequests = numberOfPieces; rig.Manager.PieceManager.AddPieceRequests(id); requests = (RequestBundle)id.Dequeue(); await ReceiveFirst(); Assert.AreEqual(url, requestedUrl[0]); }
/// <param name="id">The peer whose message queue you want to start processing</param> internal void ProcessQueue(PeerId id) { if (id.QueueLength == 0) { id.ProcessingQueue = false; return; } PeerMessage msg = id.Dequeue(); if (msg is PieceMessage) { using (ManualResetEvent handle = new ManualResetEvent(false)) { PieceMessage pm = (PieceMessage)msg; pm.Data = BufferManager.EmptyBuffer; ClientEngine.BufferManager.GetBuffer(ref pm.Data, pm.ByteLength); engine.DiskManager.QueueRead(id.TorrentManager, pm.StartOffset + ((long) pm.PieceIndex * id.TorrentManager.Torrent.PieceLength), pm.Data, pm.RequestLength, delegate { handle.Set(); }); handle.WaitOne(); id.PiecesSent++; } } try { SendMessage(id, msg, this.messageSentCallback); } catch (Exception e) { CleanupSocket(id, "Exception calling SendMessage: " + e.Message); } }
public void Advertise2() { unchoker.UnchokeReview(); Assert.AreEqual(unchoker.MaxAdvertised, peer.QueueLength, "#2"); for (int i = 0; i < unchoker.MaxAdvertised; i++) { Assert.AreEqual(i, ((HaveMessage)peer.Dequeue()).PieceIndex, "#3." + i); } }
protected virtual void HandleCancelMessage(PeerId id, CancelMessage message) { PeerMessage msg; for (int i = 0; i < id.QueueLength; i++) { msg = id.Dequeue(); if (!(msg is PieceMessage)) { id.Enqueue(msg); continue; } PieceMessage piece = msg as PieceMessage; if (!(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) { id.Enqueue(msg); } else { id.IsRequestingPiecesCount--; } } for (int i = 0; i < id.PieceReads.Count; i++) { if (id.PieceReads[i].PieceIndex == message.PieceIndex && id.PieceReads[i].StartOffset == message.StartOffset && id.PieceReads[i].RequestLength == message.RequestLength) { id.IsRequestingPiecesCount--; id.PieceReads.RemoveAt(i); break; } } }
/// <summary> /// Checks the send queue of the peer to see if there are any outstanding pieces which they requested /// and rejects them as necessary /// </summary> /// <param name="Peer"></param> private void RejectPendingRequests(PeerId Peer) { PeerMessage message; PieceMessage pieceMessage; int length = Peer.QueueLength; for (int i = 0; i < length; i++) { message = Peer.Dequeue(); if (!(message is PieceMessage)) { Peer.Enqueue(message); continue; } pieceMessage = (PieceMessage)message; // If the peer doesn't support fast peer, then we will never requeue the message if (!(Peer.SupportsFastPeer && ClientEngine.SupportsFastPeer)) { Peer.IsRequestingPiecesCount--; continue; } // If the peer supports fast peer, queue the message if it is an AllowedFast piece // Otherwise send a reject message for the piece if (Peer.AmAllowedFastPieces.Contains(pieceMessage.PieceIndex)) Peer.Enqueue(pieceMessage); else { Peer.IsRequestingPiecesCount--; Peer.Enqueue(new RejectRequestMessage(pieceMessage)); } } }
/// <summary> /// This method should be called to begin processing messages stored in the SendQueue /// </summary> /// <param name="id">The peer whose message queue you want to start processing</param> internal void ProcessQueue(PeerId id) { if (id.QueueLength == 0) { id.ProcessingQueue = false; return; } PeerMessage msg = id.Dequeue(); if (msg is PieceMessage) id.PiecesSent++; try { SendMessage(id, msg, this.messageSentCallback); } catch (Exception e) { CleanupSocket(id, "Exception calling SendMessage: " + e.Message); } }