public PiecePicker(IBtClient client, HandlerExchange exchange, IRequestStrategy requestStrategy, int blockLen, CancellationToken?cancelToken) { _pickerTask = new Task(StartRequesting); _client = client; _exchange = exchange; RequestStrategy = requestStrategy; _blockLen = blockLen; _myCancelTokenOwner = new CancellationTokenSource(); _outCancelToken = cancelToken ?? _myCancelTokenOwner.Token; }
public void StartAcceptingPeers(HandlerExchange handlerExchange) { if (_handlerExchange == null) { throw new ArgumentNullException("handlerExchange"); } _handlerExchange = handlerExchange; try { _listener.Start(); _listenerTask.Start(); } catch (Exception e) { Debug.WriteLine($"ConnectionHub: Listener task is dead, exception {e}"); } }
/// <summary> /// Creates new BtClient /// </summary> /// <param name="meta">Torrent metainfo</param> /// <param name="clientEndPoint">Client's external network endpoint. Must be accessible by other peers</param> /// <param name="defaultEncoding">Message text encoding</param> /// <param name="output">Output stream. If torrent contains multiple files </param> /// <param name="blockLen">Piece block length in bytes. 10^14 bytes if not specified</param> /// <param name="fileName">File name to download. If not specified all files will be downloaded</param> /// <param name="dhtEndPoint">Mainline DHT's client endpoint. DHT will not be used if parameter is null</param> /// <param name="storage">Storage for caching pieces. If not specified MemCachedPieceStorage will be used</param> /// <param name="cancelToken">Requesting cancel on this CancellationToken causes forcefull shutdown of client</param> public BtClient(Metainfo meta, IPEndPoint clientEndPoint, Encoding defaultEncoding, Stream output, int blockLen = 16384, string fileName = null, PiecePickStrategy piecePickStrategy = PiecePickStrategy.RarestFirst, IPEndPoint dhtEndPoint = null, IPieceStorage storage = null, CancellationToken?cancelToken = null) { Metainfo = meta; _endPoint = clientEndPoint; DefaultEncoding = defaultEncoding; _peerId = GeneratePeerId(); Handshake = CalcHandshake(); BlockLength = blockLen; BlocksInPieceCount = Metainfo.PieceLength / BlockLength; AnnounceManager = new AnnounceManager(this, Metainfo.Announces); IResourcePool <Peers.Peer> peersPool = AnnounceManager; if (dhtEndPoint != null) { MainlineManager = new MainlineManagerExt(clientEndPoint, dhtEndPoint, meta.InfoHash); peersPool = new MergedPool <Peer>(new IResourcePool <Peer>[] { AnnounceManager, MainlineManager }); } if (storage == null) { storage = new FileStorage(Metainfo, BlockLength); } PieceStorage = storage; BitField piecesHave = PieceStorage.GetValidPieces(); IRequestStrategy rqStrat = null; switch (piecePickStrategy) { case PiecePickStrategy.RarestFirst: RarestFirstRqStrategy rarestFirstRqStrategy = new RarestFirstRqStrategy(Metainfo.PiecesCount, piecesHave); rqStrat = rarestFirstRqStrategy; PeerStateCache = new PeerStateCache(rarestFirstRqStrategy); break; case PiecePickStrategy.Random: rqStrat = new RandomPieceRqStrategy(Metainfo.PiecesCount, piecesHave); break; case PiecePickStrategy.Sequential: rqStrat = new SequentialPieceRqStrategy(Metainfo.PiecesCount); break; case PiecePickStrategy.SequentialOneFile: if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException("fileName"); } rqStrat = new SequentialPieceRqStrategyOneFile(Metainfo, fileName); break; default: break; } if (PeerStateCache == null) { PeerStateCache = new PeerStateCache(); } ConnectionManager = new ConnectionHub(this, clientEndPoint, peersPool, PeerStateCache); HandlerExchange = new HandlerExchange(ConnectionManager, PeerStateCache); PiecePicker = new PiecePicker(this, HandlerExchange, rqStrat, BlockLength, cancelToken); }