最近在编写一个ftp客户端,已经实现了断点续传等功能,但是如果我想下载多个文件 它就会一个一个的下载 不能同时下载 然后就把建立连接 下载文件的方法写在了一个继承了Thread的类(DownloadThread)里,每次点击下载时就传入相应参数新建一个可以建立连接和下载文件的类(DownloadThread),可是这样做的话又成了这样的效果:点击一个文件,开始下载,再点击一个文件,上一个文件的进度条就停了,然后开始了新选中的文件的下载。请问怎么样才能实现多个文件的同时下载
调试欢乐多
public static Socket ftpSocket;
public static ServerSocket serverSocket;
public static Socket dataSocket;
public static InputStream serverInput;
public static PrintStream serverOutput;
public static BufferedReader serverReader;
public static boolean passiveFlag = true;
public static String savepath;
public DownLoadThread(Socket socket, String savepath) {
ftpSocket = socket;
this.savepath = savepath;
this.start();
}
public void run() {
try {
serverOutput = new PrintStream(new BufferedOutputStream(ftpSocket.getOutputStream()), true, "GBK");
serverReader = new BufferedReader(new InputStreamReader(ftpSocket.getInputStream()));
readRespond();
doLoginFTP("ftptest", "ftptest");
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* 执行登录
* @param user
* @param pswd
* @return
*/
public boolean doLoginFTP(String user, String pswd) {
String responseStr = doFTPCommand("USER " + user);
if(responseStr.length() > 0) {
responseStr = doFTPCommand("PASS " + pswd);
if(responseStr.length() > 0){
return true;
}
}
return false;
}
/**
* 下载指定文件
* @param filepath
* @param savepath
*/
public void download(String filepath, String savepath) {
String filename = filepath.substring(filepath.lastIndexOf("/") + 1, filepath.length());
BufferedInputStream data_input = null;
BufferedOutputStream data_output = null;
byte[] temp = new byte[Constant.TEMP_BYTE_LENGTH];
try {
doFTPCommand("TYPE I");
dataSocket = getDataSocket();
doFTPCommand("RETR " + filepath);
data_input = new BufferedInputStream(dataSocket.getInputStream());
data_output = new BufferedOutputStream(new FileOutputStream(new File(savepath + File.separator + filename)));
int read = 0;
while((read = data_input.read(temp, 0, temp.length)) != -1) {
data_output.write(temp, 0, read);
data_output.flush();
}
data_output.close();
readRespond();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 得到传输数据的Socket
* <br>分两种情况
* <br>ftp链接分为两种模式:主动模式和被动模式
* <p>主动模式(使用PORT命令):
* <br>客户端链接服务端后,客户端打开某个端口供服务端链接以传输数据
* <br>所以在这种模式下要根据客户端打开的端口首先得到ServerSocket,然后得到传输数据的Socket
* <br>serverSocket = new ServerSocket(port);
* <br>dataSocket = serverSocket.accept();
* <p>被动模式(使用PASV命令):
* <br>客户端链接服务端后,服务端打开某个端口供客户端链接以传输数据
* <br>所以在这种模式下要根据服务端打开的端口和服务端IP直接得到传输数据的Socket
* <br>执行PASV命令,得到如下格式的信息
* <br>227 Entering Passive Mode (127,0,0,1,5,31)
* <br>然后解析此信息,根据IP和port
* <br>dataSocket = new Socket(address, port);
* @return
* @throws IOException
* @throws UnknownHostException
*/
private Socket getDataSocket() throws UnknownHostException, IOException {
if(passiveFlag){
String responseStr = doFTPCommand("PASV");
int index = responseStr.indexOf("(");
int lastindex = responseStr.lastIndexOf(")");
String str = responseStr.substring(index + 1, lastindex);
String address =
str.split(",")[0] + "." +
str.split(",")[1] + "." +
str.split(",")[2] + "." +
str.split(",")[3];
int port = Integer.parseInt(str.split(",")[5]) + 256 * Integer.parseInt(str.split(",")[4]);
dataSocket = new Socket(address, port);
} else {
serverSocket = new ServerSocket(123);
dataSocket = serverSocket.accept();
}
return dataSocket;
}
/**
* 执行FTP命令
* @param command
*/
public String doFTPCommand(String command) {
System.out.println("Client:--->\n" + command + "\n");
sendRequest(command);
String responStr = readRespond();
System.out.println("Server:<---\n" + responStr + "\n");
return responStr;
}
/**
* 向服务端发送命令
* @param request
* @return
*/
public void sendRequest(String request){
serverOutput.print(request + "\r\n");
serverOutput.flush();
}
public String readRespond() {
boolean isMultiLine = false;
try {
if (ftpSocket.isClosed())
throw new IOException("Server Disconnected!");
String str = serverReader.readLine() + '\n';
String result_str = str;
if (str != null && str.length() >=4 && str.charAt(3) == '-') {
isMultiLine = true;
String respond_no = str.substring(0, 3);
do {
str = serverReader.readLine() + '\n';
result_str = result_str + str;
} while(!(str.length() >= 4 && str.substring(0, 3).equals(respond_no) && str.charAt(3) == ' '));
}
// 读取服务器反馈以"XXX "开头的剩余部分。
while (isMultiLine && serverReader.ready()) {
str = serverReader.readLine();
result_str = result_str + str;
}
return result_str;
} catch(Exception e) {
return "";
}
}
}