/** * 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); } } } }
public void addTorrent(SharedTorrent torrent) throws IOException, InterruptedException { torrent.init(); if (!torrent.isInitialized()) { torrent.close(); return; } this.torrents.put(torrent.getHexInfoHash(), torrent); // Initial completion test if (torrent.isComplete()) { torrent.setClientState(ClientState.SEEDING); } else { torrent.setClientState(ClientState.SHARING); } this.announce.addTorrent(torrent, this); }
/** Tells whether we are a seed for the torrent we're sharing. */ public boolean isSeed(String hexInfoHash) { SharedTorrent t = this.torrents.get(hexInfoHash); return t != null && t.isComplete(); }