예제 #1
0
  /**
   * Display information about the BitTorrent client state.
   *
   * <p>This emits an information line in the log about this client's state. It includes the number
   * of choked peers, number of connected peers, number of known peers, information about the
   * torrent availability and completion and current transmission rates.
   */
  public synchronized void info() {
    float dl = 0;
    float ul = 0;
    int numConnected = 0;
    for (SharingPeer peer : getConnectedPeers()) {
      dl += peer.getDLRate().get();
      ul += peer.getULRate().get();
      numConnected++;
    }

    for (SharedTorrent torrent : this.torrents.values()) {
      logger.debug(
          "{} {}/{} pieces ({}%) [{}/{}] with {}/{} peers at {}/{} kB/s.",
          new Object[] {
            torrent.getClientState().name(),
            torrent.getCompletedPieces().cardinality(),
            torrent.getPieceCount(),
            String.format("%.2f", torrent.getCompletion()),
            torrent.getAvailablePieces().cardinality(),
            torrent.getRequestedPieces().cardinality(),
            numConnected,
            this.peers.size(),
            String.format("%.2f", dl / 1024.0),
            String.format("%.2f", ul / 1024.0),
          });
    }
  }
예제 #2
0
  /**
   * Piece download completion handler.
   *
   * <p>When a piece is completed, and valid, we announce to all connected peers that we now have
   * this piece.
   *
   * <p>We use this handler to identify when all of the pieces have been downloaded. When that's the
   * case, we can start the seeding period, if any.
   *
   * @param peer The peer we got the piece from.
   * @param piece The piece in question.
   */
  @Override
  public void handlePieceCompleted(SharingPeer peer, Piece piece) throws IOException {
    final SharedTorrent torrent = peer.getTorrent();
    synchronized (torrent) {
      if (piece.isValid()) {
        // Make sure the piece is marked as completed in the torrent
        // Note: this is required because the order the
        // PeerActivityListeners are called is not defined, and we
        // might be called before the torrent's piece completion
        // handler is.
        torrent.markCompleted(piece);
        logger.debug(
            "Completed download of {}, now has {}/{} pieces.",
            new Object[] {
              piece, torrent.getCompletedPieces().cardinality(), torrent.getPieceCount()
            });

        // Send a HAVE message to all connected peers
        PeerMessage have = PeerMessage.HaveMessage.craft(piece.getIndex());
        for (SharingPeer remote : getConnectedPeers()) {
          remote.send(have);
        }
      }

      if (torrent.isComplete()) {
        logger.info("Last piece validated and completed, " + "download is complete.");
        torrent.finish();

        try {
          this.announce
              .getCurrentTrackerClient(torrent)
              .announce(
                  TrackerMessage.AnnounceRequestMessage.RequestEvent.COMPLETED, true, torrent);
        } catch (AnnounceException ae) {
          logger.warn("Error announcing completion event to " + "tracker: {}", ae.getMessage());
        }

        torrent.setClientState(ClientState.SEEDING);
        if (seed == 0) {
          peer.unbind(false);
          this.announce.removeTorrent(torrent);
        }
      }
    }
  }