jBittorrentAPI
Class DownloadManager

java.lang.Object
  extended by jBittorrentAPI.DownloadManager
All Implemented Interfaces:
java.util.EventListener, ConListenerInterface, DTListener, PeerUpdateListener

public class DownloadManager
extends java.lang.Object
implements DTListener, PeerUpdateListener, ConListenerInterface

Object that manages all concurrent downloads. It chooses which piece to request to which peer.


Field Summary
private  ConnectionListener cl
           
private  byte[] clientID
           
private  java.util.BitSet isComplete
           
private  java.util.BitSet isRequested
           
private  long lastTrackerContact
           
private  long lastUnchoking
           
private  long left
           
private  long length
           
private  int maxConnectionNumber
           
private  int nbOfFiles
           
private  int nbPieces
           
private  short optimisticUnchoke
           
private  java.io.RandomAccessFile[] output_files
           
private  java.util.LinkedHashMap<java.lang.String,java.util.BitSet> peerAvailabilies
           
private  java.util.LinkedHashMap<java.lang.String,Peer> peerList
           
private  Piece[] pieceList
           
private  PeerUpdater pu
           
private  java.util.TreeMap<java.lang.String,DownloadTask> task
           
private  TorrentFile torrent
           
private  java.util.List unchokeList
           
(package private)  java.util.LinkedHashMap unchoken
           
 
Constructor Summary
DownloadManager(TorrentFile torrent, byte[] clientID)
          Create a new manager according to the given torrent and using the client id provided
 
Method Summary
 void addActiveTask(java.lang.String id, DownloadTask dt)
          Add the download task to the list of active (i.e.
 void blockUntilCompletion()
          Periodically call the unchokePeers method.
 int cardinalityR()
          Returns the number of pieces currently requested to peers
 int checkTempFiles()
          Check the existence of the files specified in the torrent and if necessary, create them
private  int choosePiece2Download(java.lang.String id)
          Returns the index of the piece that could be downloaded by the peer in parameter
 void closeTempFiles()
          Close all open files
 void connectionAccepted(java.net.Socket s)
          Called when a new peer connects to the client.
 byte[] getBitField()
          Compute the bitfield byte array from the isComplete BitSet
 Piece getPiece(int index)
          Returns the piece with the given index
 byte[] getPieceBlock(int piece, int begin, int length)
          Get a piece block from the existing file(s)
 byte[] getPieceFromFiles(int piece)
          Load piece data from the existing files
 boolean isComplete()
          Check if the current download is complete
 boolean isPieceComplete(int piece)
          Check if the piece with the given index is complete and verified
 boolean isPieceRequested(int piece)
          Check if the piece with the given index is requested by a peer
private  void optimisticUnchoke()
           
 void peerAvailability(java.lang.String peerID, java.util.BitSet has)
          Update the piece availabilities for a given peer
 void peerReady(java.lang.String peerID)
          Received when a task is ready to download or upload.
 void peerRequest(java.lang.String peerID, int piece, int begin, int length)
          Received when a peer request a piece.
 void pieceCompleted(java.lang.String peerID, int i, boolean complete)
          Received when a piece has been fully downloaded by a task.
 void pieceRequested(int i, boolean requested)
          Set the status of the piece to requested or not
 java.lang.String requestedBits()
          Returns a String representing the piece being requested by peers.
 void savePiece(int piece)
          Save a piece in the corresponding file(s)
 void setComplete(int piece, boolean is)
          Mark a piece as complete or not according to the parameters
 void setRequested(int piece, boolean is)
          Mark a piece as requested or not according to the parameters
 boolean startListening(int minPort, int maxPort)
          Create the ConnectionListener to accept incoming connection from peers
 void startTrackerUpdate()
          Create and start the peer updater to retrieve new peers sharing the file
 void stopTrackerUpdate()
          Stop the tracker updates
 void taskCompleted(java.lang.String id, int reason)
          Removes a task and peer after the task sends a completion message.
 boolean testComplete(int piece)
           
private  void unchokePeers()
          Choose which of the connected peers should be unchoked and authorized to upload from this client.
 void updateFailed(int error, java.lang.String message)
          Called when an update try fail.
 void updatePeerList(java.util.LinkedHashMap list)
          Given the list in parameter, check if the peers are already present in the peer list.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

cl

private ConnectionListener cl

clientID

private byte[] clientID

isComplete

private java.util.BitSet isComplete

isRequested

private java.util.BitSet isRequested

lastTrackerContact

private long lastTrackerContact

lastUnchoking

private long lastUnchoking

left

private long left

length

private long length

maxConnectionNumber

private int maxConnectionNumber

nbOfFiles

private int nbOfFiles

nbPieces

private int nbPieces

optimisticUnchoke

private short optimisticUnchoke

output_files

private java.io.RandomAccessFile[] output_files

peerAvailabilies

private java.util.LinkedHashMap<java.lang.String,java.util.BitSet> peerAvailabilies

peerList

private java.util.LinkedHashMap<java.lang.String,Peer> peerList

pieceList

private Piece[] pieceList

pu

private PeerUpdater pu

task

private java.util.TreeMap<java.lang.String,DownloadTask> task

torrent

private TorrentFile torrent

unchokeList

private java.util.List unchokeList

unchoken

java.util.LinkedHashMap unchoken
Constructor Detail

DownloadManager

public DownloadManager(TorrentFile torrent,
                       byte[] clientID)
Create a new manager according to the given torrent and using the client id provided

Parameters:
torrent - TorrentFile
clientID - byte[]
Method Detail

addActiveTask

public void addActiveTask(java.lang.String id,
                          DownloadTask dt)
Add the download task to the list of active (i.e. Handshake is ok) tasks

Specified by:
addActiveTask in interface DTListener
Parameters:
id - String
dt - DownloadTask

blockUntilCompletion

public void blockUntilCompletion()
Periodically call the unchokePeers method. This is an infinite loop. User have to exit with Ctrl+C, which is not good... Todo is change this method...


cardinalityR

public int cardinalityR()
Returns the number of pieces currently requested to peers

Returns:
int

checkTempFiles

public int checkTempFiles()
Check the existence of the files specified in the torrent and if necessary, create them

Returns:
int

choosePiece2Download

private int choosePiece2Download(java.lang.String id)
Returns the index of the piece that could be downloaded by the peer in parameter

Parameters:
id - The id of the peer that wants to download
Returns:
int The index of the piece to request

closeTempFiles

public void closeTempFiles()
Close all open files


connectionAccepted

public void connectionAccepted(java.net.Socket s)
Called when a new peer connects to the client. Check if it is already registered in the peer list, and if not, create a new DownloadTask for it

Specified by:
connectionAccepted in interface ConListenerInterface
Parameters:
s - Socket

getBitField

public byte[] getBitField()
Compute the bitfield byte array from the isComplete BitSet

Returns:
byte[]

getPiece

public Piece getPiece(int index)
Returns the piece with the given index

Parameters:
index - The piece index
Returns:
Piece The piece with the given index

getPieceBlock

public byte[] getPieceBlock(int piece,
                            int begin,
                            int length)
Get a piece block from the existing file(s)

Parameters:
piece - int
begin - int
length - int
Returns:
byte[]

getPieceFromFiles

public byte[] getPieceFromFiles(int piece)
Load piece data from the existing files

Parameters:
piece - int
Returns:
byte[]

isComplete

public boolean isComplete()
Check if the current download is complete

Returns:
boolean

isPieceComplete

public boolean isPieceComplete(int piece)
Check if the piece with the given index is complete and verified

Parameters:
piece - The piece index
Returns:
boolean

isPieceRequested

public boolean isPieceRequested(int piece)
Check if the piece with the given index is requested by a peer

Parameters:
piece - The piece index
Returns:
boolean

optimisticUnchoke

private void optimisticUnchoke()

peerAvailability

public void peerAvailability(java.lang.String peerID,
                             java.util.BitSet has)
Update the piece availabilities for a given peer

Specified by:
peerAvailability in interface DTListener
Parameters:
peerID - String
has - BitSet

peerReady

public void peerReady(java.lang.String peerID)
Received when a task is ready to download or upload. In such a case, if there is a piece that can be downloaded from the corresponding peer, then request the piece

Specified by:
peerReady in interface DTListener
Parameters:
peerID - String

peerRequest

public void peerRequest(java.lang.String peerID,
                        int piece,
                        int begin,
                        int length)
Received when a peer request a piece. If the piece is available (which should always be the case according to Bittorrent protocol) and we are able and willing to upload, the send the piece to the peer

Specified by:
peerRequest in interface DTListener
Parameters:
peerID - String
piece - int
begin - int
length - int

pieceCompleted

public void pieceCompleted(java.lang.String peerID,
                           int i,
                           boolean complete)
Received when a piece has been fully downloaded by a task. The piece might have been corrupted, in which case the manager will request it again later. If it has been successfully downloaded and verified, the piece status is set to 'complete', a 'HAVE' message is sent to all connected peers and the piece is saved into the corresponding file(s)

Specified by:
pieceCompleted in interface DTListener
Parameters:
peerID - String
i - int
complete - boolean

pieceRequested

public void pieceRequested(int i,
                           boolean requested)
Set the status of the piece to requested or not

Specified by:
pieceRequested in interface DTListener
Parameters:
i - int
requested - boolean

requestedBits

public java.lang.String requestedBits()
Returns a String representing the piece being requested by peers. Used only for pretty-printing.

Returns:
String

savePiece

public void savePiece(int piece)
Save a piece in the corresponding file(s)

Parameters:
piece - int

setComplete

public void setComplete(int piece,
                        boolean is)
Mark a piece as complete or not according to the parameters

Parameters:
piece - The index of the piece to be updated
is - True if the piece is now complete, false otherwise

setRequested

public void setRequested(int piece,
                         boolean is)
Mark a piece as requested or not according to the parameters

Parameters:
piece - The index of the piece to be updated
is - True if the piece is now requested, false otherwise

startListening

public boolean startListening(int minPort,
                              int maxPort)
Create the ConnectionListener to accept incoming connection from peers

Parameters:
minPort - The minimal port number this client should listen on
maxPort - The maximal port number this client should listen on
Returns:
True if the listening process is started, false else

startTrackerUpdate

public void startTrackerUpdate()
Create and start the peer updater to retrieve new peers sharing the file


stopTrackerUpdate

public void stopTrackerUpdate()
Stop the tracker updates


taskCompleted

public void taskCompleted(java.lang.String id,
                          int reason)
Removes a task and peer after the task sends a completion message. Completion can be caused by an error (bad request, ...) or simply by the end of the connection

Specified by:
taskCompleted in interface DTListener
Parameters:
id - Task idendity
reason - Reason of the completion

testComplete

public boolean testComplete(int piece)

unchokePeers

private void unchokePeers()
Choose which of the connected peers should be unchoked and authorized to upload from this client. A peer gets unchoked if it is not interested, or if it is interested and has one of the 5 highest download rate among the interested peers. \r\n Every 3 times this method is called, calls the optimisticUnchoke method, which unchoke a peer no matter its download rate, in a try to find a better source


updateFailed

public void updateFailed(int error,
                         java.lang.String message)
Called when an update try fail. At the moment, simply display a message

Specified by:
updateFailed in interface PeerUpdateListener
Parameters:
error - int
message - String

updatePeerList

public void updatePeerList(java.util.LinkedHashMap list)
Given the list in parameter, check if the peers are already present in the peer list. If not, then add them and create a new task for them

Specified by:
updatePeerList in interface PeerUpdateListener
Parameters:
list - LinkedHashMap