package cn.itcast.download;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.StringTokenizer;
/**
* ����FTP�ϴ��ļ�ʵ��
*/
public class FTPUpload {
Socket socket = null;
BufferedReader reader = null;
BufferedWriter writer = null;
public synchronized void connect(String host) throws IOException {
connect(host, 21);
}
public synchronized void connect(String host, int port) throws IOException {
connect(host, port, "anonymous", "anonymous");
}
public synchronized void connect(String host, int port, String user,
String pass) {
try {
socket = new Socket(host, port);//����ָ��ͨ��
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String line = reader.readLine();//������FTP��������õ����ص����ݣ��磺220 Serv-U FTP Server v6.3 for WinSock ready.
System.out.println("step1 ----- " + line);
sendCommand("USER " + user);// �����¼�û���
line = reader.readLine();//�����������磺331 User name okay, need password
System.out.println("step2 -----" + line);
sendCommand("PASS " + pass);// �����¼����
line = reader.readLine();//�����������磺230 User logged in, proceed
System.out.println("step3 -----" + line);
} catch (UnknownHostException ex) {
System.out.println("Couldn't find the Ftp Server");
} catch (IOException ex) {
System.out.println("IOException");
}
}
/**
* �˳���¼
*/
public synchronized void disconnect() throws IOException {
try {
sendCommand("QUIT");
//���������أ�221 Goodbye!
System.out.println("last step ----- " + reader.readLine());
} finally {
socket = null;
}
}
/**
* ��ȡָ��·���µ��ļ��б�
* @param serverPath
* @throws IOException
*/
public synchronized void listFiles(String serverPath) throws IOException {
writer.write("cwd " + serverPath + "\r\n"); //�ı�Ŀ¼
writer.flush();
System.out.println(reader.readLine());
sendCommand("PASV");//����PASV����Ҫ��������ѷ����������������ӵ�IP�Ͷ˿ڷ����ͻ��ˣ��ɿͻ������ӵ�����������������
String response = reader.readLine();//���ظ�ʽ��227 Entering Passive Mode (220,100,23,11,30,4)
String ip = null;
int port1 = -1;
int opening = response.indexOf('(');
int closing = response.indexOf(')', opening + 1);
if (closing > 0) {
//��������������ݸ�ʽΪ��220,100,23,11,30,4��ǰ���ĸ�����ΪIP,���������������ڵõ��˿ں�.�˿�=30*256+4=7684
String dataLink = response.substring(opening + 1, closing);
StringTokenizer tokenizer = new StringTokenizer(dataLink, ",");
try {
ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + "."
+ tokenizer.nextToken() + "." + tokenizer.nextToken();
port1 = Integer.parseInt(tokenizer.nextToken()) * 256
+ Integer.parseInt(tokenizer.nextToken());
} catch (Exception e) {
throw new IOException("SimpleFTP received bad data link information: "+ response);
}
}
System.out.println(ip + " " + port1);
writer.write("LIST " + "\r\n");//������ļ����г��ļ���Ϣ�������Ŀ¼���г��ļ��б�
writer.flush();
Socket dataSocket = new Socket(ip, port1);
reader.readLine();
BufferedReader dis = new BufferedReader(new InputStreamReader(dataSocket.getInputStream()));
String s = "";
while ((s = dis.readLine()) != null) {
String l = new String(s.getBytes("ISO-8859-1"), "utf-8");
System.out.println(l);
}
dis.close();
dataSocket.close();
reader.readLine();
}
public synchronized boolean upload(String lfilepath, String serverPath)
throws IOException {
File file = new File(lfilepath);
if (file.isDirectory()) {
throw new IOException("SimpleFTP cannot upload a directory.");
}
String filename = file.getName();
BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
writer.write("cwd " + serverPath + "\r\n");
writer.flush();
System.out.println(reader.readLine());
sendCommand("PASV");
String response = reader.readLine();//���ظ�ʽ��227 Entering Passive Mode (220,100,23,11,30,4)
if (!response.startsWith("227 ")) {
throw new IOException("SimpleFTP could not request passive mode: "+ response);
}
String ip = null;
int port = -1;
int opening = response.indexOf('(');
int closing = response.indexOf(')', opening + 1);
if (closing > 0) {
String dataLink = response.substring(opening + 1, closing);
StringTokenizer tokenizer = new StringTokenizer(dataLink, ",");
try {
ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + "."
+ tokenizer.nextToken() + "." + tokenizer.nextToken();
port = Integer.parseInt(tokenizer.nextToken()) * 256 + Integer.parseInt(tokenizer.nextToken());
} catch (Exception e) {
throw new IOException("SimpleFTP received bad data link information: "+ response);
}
}
System.out.println(ip + " " + port);
sendCommand("STOR " + filename);
Socket dataSocket = new Socket(ip, port);//��������ͨ��
response = reader.readLine();
BufferedOutputStream output = new BufferedOutputStream(dataSocket.getOutputStream());
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
output.flush();
output.close();
input.close();
response = reader.readLine();//226 Transfer complete
return response.startsWith("226 ");
}
private void sendCommand(String com) throws IOException {
if (socket == null) {
throw new IOException("SimpleFTP is not connected.");
}
try {
writer.write(com + "\r\n");
writer.flush();
} catch (IOException e) {
socket = null;
throw e;
}
}
public static void main(String args[]) throws IOException {
String host = "127.0.0.1";
int port = 21;
String uname = "test";
String pwd = "test";
FTPUpload ftpUpload = new FTPUpload();
ftpUpload.connect(host, port, uname, pwd);
ftpUpload.listFiles("itcast\\images");
// fr.upload("D:\\xxx.jpg");
ftpUpload.disconnect();
}
}
/*
FTP��
�������Э�飬�� HTTP Э�飬FTP Э��Ҫ����һЩ����һ��� C/S Ӧ�ò�ͬ������һ���C/S Ӧ�ó���һ��ֻ�Ὠ��һ�� Socket ���ӣ�
�������ͬʱ����������˺Ϳͻ��˵�������������ݴ��䡣��FTPЭ���н����������ݷֿ����͵ķ��������Ч�ʡ�
FTP ʹ�� 2 ���˿ڣ�һ�����ݶ˿ں�һ������˿ڣ�Ҳ�������ƶ˿ڣ����������˿�һ����21 ������˿ڣ��� 20 �����ݶ˿ڣ���
���� Socket ��������������� Socket �����ڴ������ݡ�ÿһ�� FTP �����֮��FTP ���������᷵��һ���ַ�����
���а���һ����Ӧ�����һЩ˵����Ϣ�����еķ�������Ҫ�������ж������Ƿɹ�ִ���ˡ�
����˿�
һ����˵���ͻ�����һ�� Socket �������� FTP ����������ض˿ڣ������� FTP ����ķ��ͺͽ��շ��ص���Ӧ��Ϣ��
һЩ�����硰��¼�������ı�Ŀ¼������ɾ���ļ���������������ӷ�������Ϳ���ɡ�
���ݶ˿�
���������ݴ���IJ�������Ҫ����ʾĿ¼�б��ϴ��������ļ���������Ҫ������һ�� Socket����ɡ�
���ʹ�ñ���ģʽ��ͨ���������˻᷵��һ���˿ںš��ͻ�����Ҫ����һ�� Socket ����������˿ڣ�
Ȼ�����ǿɸ��ݲ���������������ݻ�ͨ���¿���һ���˿ڴ��䡣
���ʹ������ģʽ��ͨ���ͻ��˻ᷢ��һ���˿ںŸ��������ˣ���������˿ڼ�������������Ҫ���ӵ��ͻ��˿�����������ݶ˿ڣ�
���������ݵĴ��䡣
����� FTP ������ģʽ�ͱ���ģʽ��һ���Ľ��ܡ�
����ģʽ (PORT)
����ģʽ�£��ͻ��������һ������ 1024 �Ķ˿��������������˿� P���� 21 �˿ڣ��������ӣ�ͬʱ����N +1 �˿ڼ�����
������������� ��port N+1�� ����ɷ����������Լ������ݶ˿� (20) �������ӵ��ͻ���ָ�������ݶ˿� (N+1)��
FTP �Ŀͻ���ֻ�Ǹ��߷������Լ��Ķ˿ںţ��÷����������ӿͻ���ָ���Ķ˿ڡ����ڿͻ��˵ķ���ǽ��˵��
���Ǵ��ⲿ���ڲ������ӣ����ܻᱻ������
����ģʽ (PASV)
Ϊ�˽�����������ͻ����������⣬������һ�� FTP ���ӷ�ʽ����������ʽ���������Ӻ��������Ӷ��ɿͻ��˷���
�����ͽ���˴ӷ��������ͻ��˵����ݶ˿ڵ����ӱ�����ǽ���˵����⡣
����ģʽ�£�������һ�� FTP ����ʱ���ͻ��˴���������ı��ض˿� (N > 1024 �� N+1) ��
��һ���˿����ӷ������� 21 �˿ڣ��ύ PASV ���Ȼ�������Ὺ��һ������Ķ˿� (P > 1024 )��
�����硰227 entering passive mode (127,0,0,1,4,18)���� �������� 227 ��ͷ����Ϣ�������������Զ��Ÿ������������֣�
ǰ�ĸ�ָ�������ĵ�ַ������������������ڶ����� 256 �ټ������һ�����֣������ FTP ���������ŵ������������ݴ���Ķ˿ڡ�
��õ� 227 entering passive mode (h1,h2,h3,h4,p1,p2)����ô�˿ں��� p1*256+p2��ip ��ַΪh1.h2.h3.h4��
����ζ���ڷ���������һ���˿ڱ����š��ͻ����յ�����ȡ�ö˿ں�֮��, ��ͨ�� N+1 �Ŷ˿����ӷ������Ķ˿� P��
Ȼ���������˿�֮��������ݴ��䡣
��Ҫ�õ��� FTP ����
FTP ÿ������� 3 �� 4 ����ĸ��ɣ����������������ÿո�ֿ���ÿ������� "\r\n"������
Ҫ���ػ��ϴ�һ���ļ�������Ҫ���� FTP ��������Ȼ�����������˳���
��������У���Ҫ�õ��������� USER��PASS��SIZE��REST��CWD��RETR��PASV��PORT��QUIT��
USER: ָ���û�����ͨ���ǿ������Ӻ��һ�������������USER gaoleyi\r\n���� �û���Ϊgaoleyi ��¼��
PASS: ָ���û����롣��������� USER �����PASS gaoleyi\r\n��������Ϊ gaoleyi��
SIZE: �ӷ������Ϸ���ָ���ļ��Ĵ�С����SIZE file.txt\r\n������� file.txt �ļ����ڣ��ظ��ļ��Ĵ�С��
CWD: �ı乤��Ŀ¼���磺��CWD dirname\r\n����
PASV: �÷����������ݶ˿ڼ��������뱻��ģʽ���磺��PASV\r\n����
PORT: ���� FTP �������ͻ��˼����Ķ˿ںţ��� FTP ��������������ģʽ���ӿͻ��ˡ��磺��PORT h1,h2,h3,h4,p1,p2����
RETR: �����ļ�����RETR file.txt \r\n���������ļ� file.txt��
STOR: �ϴ��ļ�����STOR file.txt\r\n�����ϴ��ļ� file.txt��
REST: ������������ļ��������Թ�ָ���������ݡ��������Ӧ�ø�����Ҫ���ļ������ FTP �����REST 100\r\n��������ָ���ļ����͵�ƫ����Ϊ 100 �ֽڡ�
QUIT: �ر�������������ӡ�
FTP ��Ӧ��
�ͻ��˷��� FTP ���������������Ӧ�롣
��Ӧ������λ���ֱ����ʾ��
��һ�����ָ���������״̬��һ����ָʾ��������Ӧ�ɹ���ʧ�ܻ�������
�ڶ�����������Ӧ���͵ķ��࣬�� 2 ����������йص���Ӧ��3 �����û���֤��
�����������ṩ�˸�����ϸ����Ϣ��
��һ�����ֵĺ������£�
1 ��ʾ��������ȷ������Ϣ����δ����
2 ��ʾ�������Ѿ���ȷ������Ϣ��
3 ��ʾ��������ȷ������Ϣ�����ڴ���
4 ��ʾ��Ϣ��ʱ����
5 ��ʾ��Ϣ���ô���
�ڶ������ֵĺ������£�
0 ��ʾ���
1 ��ʾϵͳ״̬����Ϣ��
2 ��ʾ����״̬��
3 ��ʾ���û���֤�йص���Ϣ��
4 ��ʾδ���塣
5 ��ʾ���ļ�ϵͳ�йص���Ϣ��
ָ���ȫ��
ACCT <account> ϵͳ��Ȩ�ʺ�
ALLO <bytes> Ϊ�������ϵ��ļ��洢�������ֽ�
APPE <filename> ����ļ���������ͬ���ļ�
CDUP <dir path> �ı�������ϵĸ�Ŀ¼
CWD <dir path> �ı�������ϵĹ���Ŀ¼
DELE <filename> ɾ���������ϵ�ָ���ļ�
HELP <command> ����ָ��������Ϣ
LIST <name> ������ļ����г��ļ���Ϣ�������Ŀ¼���г��ļ��б�
MODE <mode> ����ģʽ��S=��ģʽ��B=��ģʽ��C=ѹ��ģʽ��
MKD <directory> �ڷ������Ͻ���ָ��Ŀ¼
NLST <directory> �г�ָ��Ŀ¼����
NOOP �������������Է������ϵij���
PASS <password> ϵͳ��¼����
PASV ����������ȴ���������
PORT <address> IP ��ַ�����ֽڵĶ˿� ID
PWD ��ʾ��ǰ����Ŀ¼
QUIT �� FTP ���������˳���¼
REIN ���³�ʼ����¼״̬����
REST <offset> ���ض�ƫ���������ļ�����
RETR <filename> �ӷ��������һأ����ƣ��ļ�
RMD <directory> �ڷ�������ɾ��ָ��Ŀ¼
RNFR <old path> �Ծ�·��������
RNTO <new path> ����·��������
SITE <params> �ɷ������ṩ��վ���������
SMNT <pathname> ����ָ���ļ��ṹ
STAT <directory> �ڵ�ǰ�����Ŀ¼�Ϸ�����Ϣ
STOR <filename> ���棨���ƣ��ļ�����������
STOU <filename> �����ļ���������������
STRU <type> ���ݽṹ��F=�ļ���R=��¼��P=ҳ�棩
SYST ���ط�����ʹ�õIJ���ϵͳ
TYPE <data type> �������ͣ�A=ASCII��E=EBCDIC��I=binary��
USER <username>> ϵͳ��¼���û���
�ϵ��ϴ�ԭ��
1����ȡ���������ļ���(LIST��SIZE)
2������������͡�APPE ���ļ�������ָ����Ҫ�ϵ��������ļ���������������ͨ�����͵����ݻḽ�ӵ�����ļ�ĩβ��
3��ʹ��RandomAccessFile.seek()ָ�����ļ�ij��λ�ÿ�ʼ��ȡ���ݲ����͡�
����ָ�����£�
Client���ӵ�FTP��������
Server����:220 Serv-U FTP Server v6.3 for WinSock ready.
Client����:USER liming
Server����:331 User name okay, need password.
Client����:PASS 123456
Server����:230 User logged in, proceed.
Client����:SIZE xxx.TXT
Server����:213 5
Client����:PASV
Server����:227 Entering Passive Mode (127,0,0,1,11,79)
Client����:APPE xxx.TXT
Server����:150 Opening ASCII mode data connection for 1.TXT.
�ͻ��˽�����һ��Socket���ӵ�127,0,0,1��11*256+79�˿ڣ�Ȼ��ʹ��RandomAccessFile.seek()ָ�����ļ�ij��λ�ÿ�ʼ��ȡ���ݲ�����
Server����:226 Transfer complete.
Client����:QUIT
Server����:221 Goodbye!
*/