Ejemplo n.º 1
0
        private void TryChoke(ChokeData data)
        {
            // Already choked
            if (data.Peer.AmChoking)
            {
                return;
            }

            if (!data.Peer.IsInterested)
            {
                // Choke him if he's not interested
                Choke(data.Peer);
            }
            else if (!_advertisedPieces.Exists(p => Equals(p.Peer, data.Peer)))
            {
                // If we have no free slots and peers are waiting, choke after 30 seconds.
                // FIXME: Choke as soon as the next piece completes *or* a larger time limit *and*
                // at least one piece has uploaded.
                data.LastChoked = DateTime.Now;
                Choke(data.Peer);
            }
        }
Ejemplo n.º 2
0
        private void TryUnchoke(ChokeData data)
        {
            // Already unchoked
            if (!data.Peer.AmChoking)
            {
                return;
            }

            // Don't unchoke if he's not interested
            if (!data.Peer.IsInterested)
            {
                return;
            }

            // Don't unchoke if we are have maxed our slots
            if (_manager.UploadingTo >= _manager.Settings.UploadSlots)
            {
                return;
            }

            data.LastUnchoked = DateTime.Now;
            Unchoke(data.Peer);
        }
Ejemplo n.º 3
0
        private void TryAdvertisePiece(ChokeData data)
        {
            // If we are seeding to this peer and we have a peer waiting to unchoke
            // don't advertise more data
            if (!data.Peer.AmChoking && PendingUnchoke)
            {
                return;
            }

            var advertised = _advertisedPieces.FindAll(p => Equals(p.Peer, data.Peer)).Count;
            int max;

            if (_manager.UploadingTo < _manager.Settings.UploadSlots)
            {
                max = MaxAdvertised;
            }
            else if (data.ShareRatio < 0.25)
            {
                max = 1;
            }
            else if (data.ShareRatio < 0.35)
            {
                max = 2;
            }
            else if (data.ShareRatio < 0.50)
            {
                max = 3;
            }
            else
            {
                max = MaxAdvertised;
            }

            if (advertised >= max)
            {
                return;
            }

            // List of pieces *not* in the swarm
            _temp.From(_bitfield).Not();

            // List of pieces that he wants that aren't in the swarm
            _temp.NAnd(data.Peer.BitField);

            // Ignore all the pieces we've already started sharing
            foreach (var p in _advertisedPieces)
            {
                _temp[p.Index] = false;
            }

            var index = 0;

            while (advertised < max)
            {
                // Get the index of the first piece we can send him
                index = _temp.FirstTrue(index, _temp.Length);
                // Looks like he's not interested in us...
                if (index == -1)
                {
                    return;
                }

                advertised++;
                data.TotalPieces++;
                data.CurrentPieces[index] = true;
                _advertisedPieces.Add(new SeededPiece(data.Peer, index,
                                                      data.Peer.TorrentManager.Torrent.PieceLength / Piece.BlockSize));
                data.Peer.Enqueue(new HaveMessage(index));
                index++;
            }
        }