Exemple #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.");
 }
        /// <summary>
        /// Request piece blocks from passed in peer list.
        /// </summary>
        /// <param name="tc"></param>
        /// <param name="pieceNumber"></param>
        /// <param name="remotePeers"></param>
        /// <param name="stopwatch"></param>
        private bool GetMoreBlocks(TorrentContext tc, UInt32 pieceNumber, Peer[] remotePeers)
        {
            bool success = true;

            tc.assemblyData.guardMutex.WaitOne();
            try
            {
                UInt32 blockOffset = 0;
                int    currentPeer = 0;
                tc.assemblyData.currentBlockRequests = 0;
                foreach (var blockThere in tc.assemblyData.pieceBuffer.BlocksPresent)
                {
                    if (!blockThere)
                    {
                        PWP.Request(remotePeers[currentPeer], pieceNumber, blockOffset, Math.Min(Constants.BlockSize, tc.GetPieceLength(pieceNumber) - blockOffset));
                        remotePeers[currentPeer].OutstandingRequestsCount++;
                        if (++tc.assemblyData.currentBlockRequests == _maximumBlockRequests)
                        {
                            break;
                        }
                        currentPeer = (currentPeer + 1) % (int)remotePeers.Length;
                    }
                    blockOffset += Constants.BlockSize;
                }
            }
            catch (Exception ex)
            {
                Log.Logger.Error(ex);
                success = false;
            }
            tc.assemblyData.guardMutex.ReleaseMutex();
            return(success);
        }
Exemple #3
0
 /// <summary>
 ///  Perform intial handsake with remote peer.
 /// </summary>
 /// <param name="manager"></param>
 public void Handshake(Manager manager)
 {
     if (manager is null)
     {
         throw new ArgumentNullException(nameof(manager));
     }
     RemotePeerID = PWP.Handshake(this, manager);
     Connected    = true;
     _network.StartReads(this);
     PWP.Bitfield(this, Tc.Bitfield);
 }
 private readonly int _maximumBlockRequests;   // Maximum requests at a time
 /// <summary>
 /// Signal to all peers in swarm that we now have the piece local so
 /// that they can request it if they need.
 /// </summary>
 /// <param name="tc"></param>
 /// <param name="pieceNumber"></param>
 private void SignalHaveToSwarm(TorrentContext tc, UInt32 pieceNumber)
 {
     foreach (var remotePeer in tc.peerSwarm.Values)
     {
         try
         {
             PWP.Have(remotePeer, pieceNumber);
         }
         catch (Exception ex)
         {
             Log.Logger.Error(ex);
             remotePeer.Close();
         }
     }
 }
 /// <summary>
 // Wait and process remote peer requests until cancelled.
 /// </summary>
 /// <param name="tc"></param>
 /// <param name="cancelTask"></param>
 private void ProcessRemotePeerRequests(TorrentContext tc, CancellationToken cancelAssemblerTask)
 {
     WaitHandle[] waitHandles = new WaitHandle[] { cancelAssemblerTask.WaitHandle };
     foreach (var remotePeer in tc.peerSwarm.Values)
     {
         try
         {
             PWP.Uninterested(remotePeer);
             PWP.Unchoke(remotePeer);
         }
         catch (Exception ex)
         {
             Log.Logger.Error(ex);
             remotePeer.Close();
         }
     }
     WaitHandle.WaitAll(waitHandles);
 }