我尝试使用ttorrent Java library
开发一个简单的 Java BitTorrent client
,但是,虽然第一次下载开始并且工作正常,但当我停止并尝试恢复时,它不起作用。
这是代码(有3个类):
一级:
package rar.torrent;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
import com.turn.ttorrent.client.Client;
import com.turn.ttorrent.client.SharedTorrent;
public class TorrentFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private static final String APRI_BTN = "APRI_BTN";
private static final String SCEGLI_BTN = "SCEGLI_BTN";
private static final String PLAY_STOP_BTN = "PLAY_STOP_BTN";
private static final String PLAY_TXT = "Play";
private static final String STOP_TXT = "Stop";
private JTextField torrentFileText = null;
private JTextField destinazioneText = null;
private JButton apriButton = null;
private JButton scegliButton = null;
private JButton playStopButton = null;
private JProgressBar jpb = null;
private JLabel peerLabel = null;
private JFileChooser torrentJFC = null;
private JFileChooser directoryJFC = null;
private SharedTorrent torrent = null;
private Client client = null;
private DownloadThread dt = null;
private File torrentFile = null;
private File destinazioneFile = null;
private Thread t = null;
public TorrentFrame (){
super("RARTorrent");
JPanel mainPanel = new JPanel(new GridLayout(5,1));
JPanel filePanel = new JPanel(new GridLayout(1,3));
JLabel label = new JLabel("Seleziona file torrent:");
torrentFileText = new JTextField(20);
torrentFileText.setText("");
torrentFileText.setEditable(false);
apriButton = new JButton("Apri");
apriButton.setActionCommand(APRI_BTN);
apriButton.addActionListener(this);
filePanel.add(label);
filePanel.add(torrentFileText);
filePanel.add(apriButton);
JPanel fileDestPanel = new JPanel(new GridLayout(1,3));
JLabel labelDest = new JLabel("Seleziona destinazioneText:");
destinazioneText = new JTextField(20);
destinazioneText.setText("");
destinazioneText.setEditable(false);
scegliButton = new JButton("Scegli");
scegliButton.setActionCommand(SCEGLI_BTN);
scegliButton.addActionListener(this);
fileDestPanel.add(labelDest);
fileDestPanel.add(destinazioneText);
fileDestPanel.add(scegliButton);
playStopButton = new JButton(PLAY_TXT);
playStopButton.setActionCommand(PLAY_STOP_BTN);
playStopButton.addActionListener(this);
jpb = new JProgressBar(0,100);
jpb.setStringPainted(true);
peerLabel = new JLabel("Download non in corso");
torrentJFC = new JFileChooser();
torrentJFC.setFileSelectionMode(JFileChooser.FILES_ONLY);
torrentJFC.setAcceptAllFileFilterUsed(false);
torrentJFC.setFileFilter(new TorrentFileFilter());
directoryJFC = new JFileChooser();
directoryJFC.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
mainPanel.add(filePanel);
mainPanel.add(fileDestPanel);
mainPanel.add(playStopButton);
mainPanel.add(jpb);
mainPanel.add(peerLabel);
this.add(mainPanel);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
private class TorrentFileFilter extends FileFilter{
@Override
public boolean accept(File f) {
String ext = null;
String s = f.getName();
int i = s.lastIndexOf('.');
if (i > 0 && i < s.length() - 1) {
ext = s.substring(i+1).toLowerCase();
}
if (ext != null && ext.equals("torrent"))
return true;
return false;
}
@Override
public String getDescription() {
return "Torrent files";
}
}
@Override
public void actionPerformed(ActionEvent arg0) {
String ev = arg0.getActionCommand();
if(ev.equalsIgnoreCase(APRI_BTN)){
int returnVal = torrentJFC.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
torrentFile = torrentJFC.getSelectedFile();
torrentFileText.setText(torrentFile.getName());
} else {
System.out.println("Chiuso 'Apri file'");
}
}
if(ev.equalsIgnoreCase(PLAY_STOP_BTN)){
if (playStopButton.getText().equalsIgnoreCase(STOP_TXT)){
client.stop();
dt.stop();
client = null;
t = null;
dt = null;
torrent = null;
playStopButton.setText(PLAY_TXT);
return;
}
if (playStopButton.getText().equalsIgnoreCase(PLAY_TXT) && !torrentFileText.getText().equalsIgnoreCase("") && !destinazioneText.getText().equalsIgnoreCase("")){
try {
torrent = SharedTorrent.fromFile(torrentFile, destinazioneFile);
client = new Client(InetAddress.getLocalHost(),torrent);
client.setMaxDownloadRate(1000.0);
client.setMaxUploadRate(50.0);
client.download();
jpb.setValue(0);
peerLabel.setText("Non in download");
dt = new DownloadThread(jpb,peerLabel,torrent);
t = new Thread (dt);
t.start();
playStopButton.setText(STOP_TXT);
} catch (IOException e) {
JOptionPane.showMessageDialog(this, e.getMessage());
}
}
}
if(ev.equalsIgnoreCase(SCEGLI_BTN)){
int returnVal = directoryJFC.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
destinazioneFile = directoryJFC.getSelectedFile();
destinazioneText.setText(destinazioneFile.getName());
} else {
System.out.println("Chiuso 'Scegli'");
}
}
}
}
二等:
package rar.torrent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import com.turn.ttorrent.client.SharedTorrent;
public class DownloadThread implements Runnable {
private JProgressBar jpb = null;
private SharedTorrent torrent = null;
private JLabel peerLabel = null;
private int completedPieces = 0;
private int pieceCount = 0;
private int availablePieces = 0;
private int requestedPieces = 0;
private String peerLabelText = "";
private boolean stop = false;
public DownloadThread(JProgressBar jpb, JLabel peerLabel, SharedTorrent torrent){
super();
this.jpb = jpb;
this.torrent = torrent;
this.peerLabel = peerLabel;
}
@Override
public void run() {
while (!torrent.isComplete() && !stop){
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
float perc = torrent.getCompletion();
int percInt = (int) perc;
int jpbValue = jpb.getValue();
if (percInt > jpbValue)
jpb.setValue(percInt);
//TODO Sistemare il bug della "," nella stringa sostituendola con il "."
String stringToFloat = jpb.getString().substring(0, jpb.getString().length() -1);
int comaChar = stringToFloat.lastIndexOf(",");
char [] transformString = stringToFloat.toCharArray();
if (comaChar > 0)
transformString [comaChar] = '.';
stringToFloat = new String(transformString);
if (perc > Float.parseFloat(stringToFloat))
jpb.setString(String.format("%.2f", perc) + "%");
completedPieces = torrent.getCompletedPieces().cardinality();
pieceCount = torrent.getPieceCount();
availablePieces = torrent.getAvailablePieces().cardinality();
requestedPieces = torrent.getRequestedPieces().cardinality();
if (isPeerLabelTextModified(cal,sdf)){
peerLabelText = completedPieces + "/" + pieceCount + " pieces [" + availablePieces + "/" + requestedPieces + "] \n" + sdf.format(cal.getTime());
peerLabel.setText(peerLabelText);
}
}
}
private boolean isPeerLabelTextModified (Calendar cal, SimpleDateFormat sdf){
String test = completedPieces + "/" + pieceCount + " pieces [" + availablePieces + "/" + requestedPieces + "] " + sdf.format(cal.getTime());
return !peerLabelText.equalsIgnoreCase(test);
}
public void stop(){
this.stop = true;
}
}
第三类:
package rar.torrent;
import javax.swing.*;
public class RARTorrent{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
new TorrentFrame();
}});
}
}
非常感谢!