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.IsInstanceOfType(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.IsInstanceOfType(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; } var msg = id.Dequeue(); var message = msg as PieceMessage; if (message != null) { using (var handle = new ManualResetEvent(false)) { var pm = message; 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, _messageSentCallback); } catch (Exception e) { CleanupSocket(id, "Exception calling SendMessage: " + e.Message); } }
/// <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) { var length = peer.QueueLength; for (var i = 0; i < length; i++) { var message = peer.Dequeue(); if (!(message is PieceMessage)) { peer.Enqueue(message); continue; } var 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)); } } }
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; } var piece = msg as PieceMessage; if (!(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) { id.Enqueue (msg); } else { id.IsRequestingPiecesCount--; } } }
protected virtual void HandleCancelMessage(PeerId id, CancelMessage message) { for (var i = 0; i < id.QueueLength; i++) { var msg = id.Dequeue(); if (!(msg is PieceMessage)) { id.Enqueue(msg); continue; } var piece = msg as PieceMessage; if ( !(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) { id.Enqueue(msg); } else { id.IsRequestingPiecesCount--; } } for (var 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> /// Performs any necessary actions required to process the message /// </summary> /// <param name="id">The Peer who's message will be handled</param> internal override void Handle(PeerId id) { 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 == this.pieceIndex && piece.StartOffset == this.startOffset && piece.RequestLength == this.requestLength)) { id.Enqueue(msg); } else { id.IsRequestingPiecesCount--; } } }
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); } }