private bool HashCheck(Block block) { //изчисляване на хеш стойността на блока var hash = hasher.ComputeHash(block.Data, 0, block.Info.Length); //сверяване на получения хеш код със този, указан в метаданните return hash.SequenceEqual(Metadata.Checksums[block.Info.Index]); }
private void BlockRead(bool success, Block block, object state) { var peer = (PeerState)state; try { if (success) { Monitor.Read(block.Info.Length); SendMessage(peer, new PieceMessage(block.Info.Index, block.Info.Offset, block.Data)); } } catch (Exception e) { HandleException(e); } }
public void AddBlock(Block block, BlockWrittenDelegate callback, object state) { try { IEnumerable<BlockPartInfo> parts = GetParts(block.Info.Index, block.Info.Offset, block.Info.Length, true); var totalLen = parts.Sum(p => p.Length); BlockWriteState data = writeCache.Get().Init(callback, (int)totalLen, block, state); Trace.Assert(parts.Any()); foreach(BlockPartInfo part in parts) { DiskIO.QueueWrite(part.FileStream, block.Data, part.FileOffset, part.DataOffset, part.Length, EndAddBlock, data); } } catch(Exception e) { OnRaisedException(new TorrentException(e.Message, e)); callback(false, state); } }
private void PieceRead(bool success, Block block, object state) { if (Stopping) return; Interlocked.Decrement(ref remainingPieces);//безопасно декрементиране на брояча int piece = (int)state; if (success) { //заключване на прочетения блок lock(block.Data) if(HashCheck(block)) { //ако хеш проверката мине, блока се маркира като наличен MarkAvailable(piece); } } //ако остават 0 парчета за проверяване, процесът е завършил //спиране и съобщение за приключване if(remainingPieces == 0) { Stop(true); OnHashingComplete(); } }
public void GetBlock(byte[] buffer, int pieceIndex, int offset, int length, BlockReadDelegate callback, object state) { try { IEnumerable<BlockPartInfo> parts = GetParts(pieceIndex, offset, length, false); var block = new Block(buffer, pieceIndex, offset, length); BlockReadState data = readCache.Get().Init(block, callback, length, state); if(parts.Count() > 1) Trace.WriteLine(pieceIndex + " is split between " + parts.Count() + " files."); foreach(BlockPartInfo part in parts) { if (part.FileStream != null) DiskIO.QueueRead(part.FileStream, buffer, part.DataOffset, part.FileOffset, part.Length, EndGetBlock, data); else { OnRaisedException(new TorrentException("Stream is null.")); callback(false, null, state); return; } } } catch(Exception e) { OnRaisedException(new TorrentException(e.Message, e)); callback(false, null, state); } }
public BlockWriteState Init(BlockWrittenDelegate callback, int remaining, Block block, object state) { Callback = callback; State = state; Remaining = remaining; Block = block; return this; }
public BlockReadState Init(Block block, BlockReadDelegate callback, int remaining, object state) { Block = block; Callback = callback; State = state; Remaining = remaining; return this; }
private void WriteBlock(PieceMessage piece) { try { var block = new Block(piece.Data, piece.Index, piece.Offset, piece.Data.Length); BlockManager.AddBlock(block, BlockWritten, block); Interlocked.Add(ref pendingWrites, piece.Data.Length); } catch(Exception e) { HandleException(e); } }