コード例 #1
0
 /// <summary>
 /// Process any piece requests in buffer and send to remote peer.
 /// </summary>
 /// <param name="cancelTask"></param>
 /// <returns></returns>
 private void PieceRequestProcessing(CancellationToken cancelTask)
 {
     try
     {
         Log.Logger.Info("Piece request processing task started...");
         while (true)
         {
             Peer         remotePeer = null;
             PieceRequest request    = pieceRequestQueue.Take(cancelTask);
             try
             {
                 Log.Logger.Info($"Piece Reqeuest {request.pieceNumber} {request.blockOffset} {request.blockSize}.");
                 if (_manager.GetPeer(request.infoHash, request.ip, out remotePeer))
                 {
                     PieceBuffer requestBuffer = GetPieceFromTorrent(remotePeer, request.pieceNumber);
                     byte[]      requestBlock  = new byte[request.blockSize];
                     Array.Copy(requestBuffer.Buffer, (Int32)request.blockOffset, requestBlock, 0, (Int32)request.blockSize);
                     PWP.Piece(remotePeer, request.pieceNumber, request.blockOffset, requestBlock);
                     remotePeer.Tc.TotalBytesUploaded += request.blockSize;
                 }
             }
             catch (Exception ex)
             {
                 Log.Logger.Error(ex);
                 // Remote peer most probably closed socket so close connection
                 remotePeer?.Close();
             }
         }
     }
     catch (Exception ex)
     {
         Log.Logger.Debug(ex);
     }
     Log.Logger.Info("Piece request processing task terminated.");
 }
コード例 #2
0
        internal BlockingCollection <PieceRequest> pieceRequestQueue;  // Piece request read queue
        /// <summary>
        /// Read/Write piece buffers to/from torrent on disk.
        /// </summary>
        /// <param name="tc"></param>
        /// <param name="transferBuffer"></param>
        /// <param name="read"></param>
        /// <summary>
        private void TransferPiece(TorrentContext tc, PieceBuffer transferBuffer, bool read)
        {
            int    bytesTransferred = 0;
            UInt64 startOffset      = transferBuffer.Number * tc.pieceLength;
            UInt64 endOffset        = startOffset + transferBuffer.Length;

            foreach (var file in tc.filesToDownload)
            {
                if ((startOffset <= (file.offset + file.length)) && (file.offset <= endOffset))
                {
                    UInt64 startTransfer = Math.Max(startOffset, file.offset);
                    UInt64 endTransfer   = Math.Min(endOffset, file.offset + file.length);
                    using (Stream stream = new FileStream(file.name, FileMode.Open))
                    {
                        stream.Seek((Int64)(startTransfer - file.offset), SeekOrigin.Begin);
                        if (read)
                        {
                            stream.Read(transferBuffer.Buffer, (Int32)(startTransfer % tc.pieceLength), (Int32)(endTransfer - startTransfer));
                        }
                        else
                        {
                            stream.Write(transferBuffer.Buffer, (Int32)(startTransfer % tc.pieceLength), (Int32)(endTransfer - startTransfer));
                        }
                    }
                    bytesTransferred += (Int32)(endTransfer - startTransfer);
                    if (bytesTransferred == tc.GetPieceLength(transferBuffer.Number))
                    {
                        break;
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Read piece from torrent
        /// </summary>
        /// <param name="remotePeer"></param>
        /// <param name="pieceNumber"></param>
        /// <returns></returns>
        private PieceBuffer GetPieceFromTorrent(Peer remotePeer, UInt32 pieceNumber)
        {
            PieceBuffer pieceBuffer = new PieceBuffer(remotePeer.Tc, pieceNumber, remotePeer.Tc.GetPieceLength(pieceNumber));

            Log.Logger.Debug($"Read piece ({pieceBuffer.Number}) from file.");
            TransferPiece(remotePeer.Tc, pieceBuffer, true);
            Log.Logger.Debug($"Piece ({pieceBuffer.Number}) read from file.");
            return(pieceBuffer);
        }
コード例 #4
0
 /// <summary>
 /// Task to take a queued download piece and write it away to the relevant file
 /// sections to which it belongs within a torrent.
 /// </summary>
 /// <param name="cancelTask"></param>
 /// <returns></returns>
 private void PieceBufferDiskWriter(CancellationToken cancelTask)
 {
     try
     {
         Log.Logger.Info("Piece Buffer disk writer task starting...");
         while (true)
         {
             PieceBuffer pieceBuffer = pieceWriteQueue.Take(cancelTask);
             Log.Logger.Debug($"Write piece ({pieceBuffer.Number}) to file.");
             if (!pieceBuffer.Tc.downloadFinished.WaitOne(0))
             {
                 TransferPiece(pieceBuffer.Tc, pieceBuffer, false);
                 pieceBuffer.Tc.TotalBytesDownloaded += pieceBuffer.Tc.GetPieceLength((pieceBuffer.Number));
                 Log.Logger.Info((pieceBuffer.Tc.TotalBytesDownloaded / (double)pieceBuffer.Tc.TotalBytesToDownload).ToString("0.00%"));
                 Log.Logger.Debug($"Piece ({pieceBuffer.Number}) written to file.");
                 if (pieceBuffer.Tc.BytesLeftToDownload() == 0)
                 {
                     pieceBuffer.Tc.downloadFinished.Set();
                 }
                 // Make sure progress call back does not termiate the task.
                 try
                 {
                     pieceBuffer.Tc.CallBack?.Invoke(pieceBuffer.Tc.CallBackData);
                 }
                 catch (Exception ex)
                 {
                     Log.Logger.Error(ex);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Log.Logger.Error(ex);
     }
     Log.Logger.Info("Piece Buffer disk writer task terminated.");
 }