示例#1
0
        public void PieceDataReceived(PeerId peer, PieceMessage message)
        {
            Piece piece;

            if (_picker.ValidatePiece(peer, message.PieceIndex, message.StartOffset, message.RequestLength, out piece))
            {
                PeerId         id      = peer;
                TorrentManager manager = id.TorrentManager;
                Block          block   = piece.Blocks [message.StartOffset / Piece.BlockSize];
                long           offset  = (long)message.PieceIndex * id.TorrentManager.Torrent.PieceLength + message.StartOffset;

                id.LastBlockReceived = DateTime.Now;
                id.TorrentManager.PieceManager.RaiseBlockReceived(new BlockEventArgs(manager, block, piece, id));
                id.TorrentManager.Engine.DiskManager.QueueWrite(manager, offset, message.Data, message.RequestLength, delegate {
                    piece.Blocks[message.StartOffset / Piece.BlockSize].Written = true;
                    ClientEngine.BufferManager.FreeBuffer(ref message.Data);
                    // If we haven't written all the pieces to disk, there's no point in hash checking
                    if (!piece.AllBlocksWritten)
                    {
                        return;
                    }

                    // Hashcheck the piece as we now have all the blocks.
                    id.Engine.DiskManager.BeginGetHash(id.TorrentManager, piece.Index, delegate(object o) {
                        byte[] hash = (byte[])o;
                        bool result = hash == null ? false : id.TorrentManager.Torrent.Pieces.IsValid(hash, piece.Index);
                        id.TorrentManager.Bitfield[message.PieceIndex] = result;

                        ClientEngine.MainLoop.Queue(delegate
                        {
                            id.TorrentManager.PieceManager.UnhashedPieces[piece.Index] = false;

                            id.TorrentManager.HashedPiece(new PieceHashedEventArgs(id.TorrentManager, piece.Index, result));
                            var peers = new List <PeerId>(piece.Blocks.Length);
                            foreach (var b in piece.Blocks.Where(b => b.RequestedOff != null && !peers.Contains(b.RequestedOff)))
                            {
                                peers.Add(b.RequestedOff);
                            }

                            foreach (var p in peers.Where(p => p.Connection != null))
                            {
                                p.Peer.HashedPiece(result);
                                if (p.Peer.TotalHashFails == 5)
                                {
                                    p.ConnectionManager.CleanupSocket(id, "Too many hash fails");
                                }
                            }

                            // If the piece was successfully hashed, enqueue a new "have" message to be sent out
                            if (result)
                            {
                                id.TorrentManager.FinishedPieces.Enqueue(piece.Index);
                            }
                        });
                    });
                });

                if (piece.AllBlocksReceived)
                {
                    _unhashedPieces[message.PieceIndex] = true;
                }
            }
        }
示例#2
0
 public virtual bool ValidatePiece(PeerId peer, int pieceIndex, int startOffset, int length, out Piece piece)
 {
     CheckOverriden();
     return(picker.ValidatePiece(peer, pieceIndex, startOffset, length, out piece));
 }