private void SendBlockRequests(PeerState peer) { //изчисляване на броя на нужните блокове var count = RequestsQueueLength - peer.PendingBlocks; for (var i = 0; i < count; i++) { //поискване на нов блок от BlockStrategistа var block = BlockStrategist.Next(peer.Bitfield); if (block != BlockInfo.Empty) { //ако адреса на блока е валиден - тоест, има нужда от нов блок, изпраща се съобщение SendMessage(peer, new RequestMessage(block.Index, block.Offset, block.Length)); //увеличаване на броя на изчакващите блокове peer.PendingBlocks++; } else if (BlockStrategist.Complete) { //ако адреса на блока е невалиден, и всички блокове са свалени //сигнализираме приключено изтегляне OnDownloadComplete(); return; } } }
private void MarkAvailable(int piece) { int blocksPerPiece = Metadata.PieceLength / Global.Instance.BlockSize; int blockSize = Global.Instance.BlockSize; for (int i = 0; i < blocksPerPiece; i++) { BlockStrategist.Received(new BlockInfo(piece, blockSize * i, blockSize)); } }
protected override void HandlePiece(PieceMessage piece, PeerState peer) { var blockInfo = new BlockInfo(piece.Index, piece.Offset, piece.Data.Length); //съобщаваме на BlockStrategistът, че сме получили блок, а той ни казва дали ни е нужен if (BlockStrategist.Received(blockInfo)) { //ако блока е нужен, записваме го WriteBlock(piece); } //понижаване на брояча за блоковете в изчакване peer.PendingBlocks--; //изпращане на нова заявка за блок към пиъра SendBlockRequests(peer); }
protected TorrentMode(BlockManager manager, BlockStrategist strategist, TorrentData metadata, TransferMonitor monitor) { //инициализация на обект за следене на пренесените данни Monitor = monitor; //обект за управляване на записа на парчета върху файловата система BlockManager = manager; //обект за управление на заявките на парчета към пиърите BlockStrategist = strategist; //обект, съдържаш метаданните на торента Metadata = metadata; //съобщение за здрависване, което се използва от този TorrentMode DefaultHandshake = new HandshakeMessage(Global.Instance.PeerId, new byte[8], Metadata.InfoHash, "BitTorrent protocol"); //конкурентен речник за съхранение на състоянието на активните пиъри Peers = new ConcurrentDictionary <string, PeerState>(); //прикачане на събитието за изключения на BlockManager-а manager.RaisedException += (s, e) => HandleException(e.Value); //инициализация на теймера за изпращане на KeepAlive съобщения KeepAliveTimer = new Timer(SendKeepAlives); }
public DownloadMode(BlockManager manager, BlockStrategist strategist, TorrentData metadata, TransferMonitor monitor) : base(manager, strategist, metadata, monitor) { strategist.HavePiece += (sender, args) => SendHaveMessages(args.Value); }
public SeedMode(BlockManager manager, BlockStrategist strategist, TorrentData metadata, TransferMonitor monitor) : base(manager, strategist, metadata, monitor) { }