设为首页 收藏本站
查看: 1779|回复: 0

[经验分享] java socket实现ftp客户端

[复制链接]

尚未签到

发表于 2016-6-9 11:31:21 | 显示全部楼层 |阅读模式
1,首先下载一个免费的ftp服务器,安装并添加用户和设置访问的文件夹,或者自己编写一个ftp服务器.
         地址:http://filezilla-project.org/
         2.运行ftp客户端程序 ftp.java.
         ftp协议是在客户机和服务器之间建立两条连接:控制连接和数据连接.
         控制连接用来发送命令,数据连接用来传输数据.
         代码如下:
         package socket;
import java.net.*;
import java.io.*;
public class Ftp {
Socket ctrlSocket;// 控制用Socket
public PrintWriter ctrlOutput;// 控制输出用的流
public BufferedReader ctrlInput;// 控制输入用的流
final int CTRLPORT = 21;// ftp 的控制用端口
ServerSocket serverDataSocket;
// openConnection方法
// 由地址和端口号构造Socket,形成控制用的流
public void openConnection(String host) throws IOException,
    UnknownHostException {
   ctrlSocket = new Socket(host, CTRLPORT);
   ctrlOutput = new PrintWriter(ctrlSocket.getOutputStream());
   ctrlInput = new BufferedReader(new InputStreamReader(ctrlSocket
     .getInputStream()));
}
// closeConnection方法
// 关闭控制用的Socket
public void closeConnection() throws IOException {
   ctrlSocket.close();
}
// showMenu方法
// 输出ftp的命令菜单
public void showMenu() {
   System.out.println(">Command?");
   System.out.print(" 1:ls");
   System.out.print(" 2:cd");
   System.out.print(" 3:get");
   System.out.print(" 4:put");
   System.out.print(" 5:ascii");
   System.out.print(" 6:binary");
   System.out.println(" 7:quit");
}
// getCommand方法
// 读取用户指定的命令序号
public String getCommand() {
   String buf = "";
   BufferedReader lineread = new BufferedReader(new InputStreamReader(
     System.in));
   while (buf.length() != 1) {
    try {
     buf = lineread.readLine();
    } catch (Exception e) {
     e.printStackTrace();
     System.exit(1);
    }
   }
   return (buf);
}
public void doLogin() {
   String loginName = "";
   String password = "";
   BufferedReader lineread = new BufferedReader(new InputStreamReader(
     System.in));
   try {
    System.out.println("请输入用户名");
    loginName = lineread.readLine();
   
    ctrlOutput.println("USER " + loginName);
    ctrlOutput.flush();
    System.out.println("请输入口令");
    password = lineread.readLine();
    ctrlOutput.println("PASS " + password);
    ctrlOutput.flush();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
public void doQuit() {
   try {
    ctrlOutput.println("QUIT ");
    ctrlOutput.flush();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
public void doCd() {
   String dirName = "";
   BufferedReader lineread = new BufferedReader(new InputStreamReader(
     System.in));
   try {
    System.out.println("请输入目录名");
    dirName = lineread.readLine();
    ctrlOutput.println("CWD " + dirName);// CWD命令
    ctrlOutput.flush();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// doLs方法
// 取得目录信息
public void doLs() {
   try {
    int n;
    byte[] buff = new byte[65530];
   
    // 建立数据连接
    Socket dataSocket = dataConnection("NLST ");
   
    // 准备读取数据用的流
    BufferedInputStream dataInput = new BufferedInputStream(dataSocket
      .getInputStream());
    // 读取目录信息
   
    while ((n = dataInput.read(buff)) > 0) {
     System.out.write(buff, 0, n);
    }
    dataSocket.close();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// dataConnection方法
// 构造与服务器交换数据用的Socket
// 再用PORT命令将端口通知服务器
public Socket dataConnection(String ctrlcmd) {
   String cmd = "PORT "; // PORT存放用PORT命令传递数据的变量
   int i;
   Socket dataSocket = null;// 传送数据用Socket
   try {
    // 得到自己的地址
    byte[] address = InetAddress.getLocalHost().getAddress();
    // 用适当的端口号构造服务器
    serverDataSocket = new ServerSocket(0,1);
   
    // 准备传送PORT命令用的数据
    for (i = 0; i < 4; ++i)
     cmd = cmd + (address & 0xff) + ",";
    cmd = cmd + (((serverDataSocket.getLocalPort()) / 256) & 0xff)
      + "," + (serverDataSocket.getLocalPort() & 0xff);
    // 利用控制用的流传送PORT命令
    ctrlOutput.println(cmd);
   
    ctrlOutput.flush();
    // 向服务器发送处理对象命令(LIST,RETR,及STOR)
    ctrlOutput.println(ctrlcmd);
    ctrlOutput.flush();
   
    // 接受与服务器的连接
           
    dataSocket = serverDataSocket.accept();
    serverDataSocket.close();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
   return dataSocket;
}
// doAscii方法
// 设置文本传输模式
public void doAscii() {
   try {
    ctrlOutput.println("TYPE A");// A模式
    ctrlOutput.flush();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// doBinary方法
// 设置二进制传输模式
public void doBinary() {
   try {
    ctrlOutput.println("TYPE I");// I模式
    ctrlOutput.flush();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// doGet方法
// 取得服务器上的文件
public void doGet() {
   String fileName = "";
   String loafile="";
   BufferedReader lineread = new BufferedReader(new InputStreamReader(
     System.in));
   try {
    int n;
    byte[] buff = new byte[1024];
    // 指定服务器上的文件名
    System.out.println("远程文件名");
    fileName = lineread.readLine();
    // 在客户端上准备接收用的文件
    System.out.println("本地文件");
    loafile=lineread.readLine();
    File local=new File(loafile);
    FileOutputStream outfile = new FileOutputStream(local);
    // 构造传输文件用的数据流
    Socket dataSocket = dataConnection("RETR " + fileName);
    BufferedInputStream dataInput = new BufferedInputStream(dataSocket
      .getInputStream());
    // 接收来自服务器的数据,写入本地文件
    while ((n = dataInput.read(buff)) > 0) {
     outfile.write(buff, 0, n);
    }
    dataSocket.close();
    outfile.close();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// doPut方法
// 向服务器发送文件
public void doPut() {
   String fileName = "";
   BufferedReader lineread = new BufferedReader(new InputStreamReader(
     System.in));
  
   try {
    int n;
    byte[] buff = new byte[1024];
    FileInputStream sendfile = null;
    // 指定文件名
    System.out.println("本地文件");
    fileName = lineread.readLine();
   
    // 准备读出客户端上的文件
    //BufferedInputStream dataInput = new BufferedInputStream(new FileInputStream(fileName));
    try {
   
     sendfile = new FileInputStream(fileName);
    } catch (Exception e) {
     System.out.println("文件不存在");
     return;
    }
            System.out.println("远程文件");
            String lonfile=lineread.readLine();
    // 准备发送数据的流
    Socket dataSocket = dataConnection("STOR " + lonfile);
    OutputStream outstr = dataSocket.getOutputStream();
    while ((n = sendfile.read(buff)) > 0) {
     outstr.write(buff, 0, n);
    }
   
    dataSocket.close();
    sendfile.close();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// execCommand方法
// 执行与各命令相应的处理
public boolean execCommand(String command) {
   boolean cont = true;
   switch (Integer.parseInt(command)) {
   case 1: // 显示服务器目录信息
    doLs();
    break;
   case 2: // 切换服务器的工作目录
    doCd();
    break;
   case 3: // 取得服务器上的文件
    doGet();
    break;
   case 4: // 向服务器发送文件
    doPut();
    break;
   case 5: // 文件传输模式
    doAscii();
    break;
   case 6: // 二进制传输模式
    doBinary();
    break;
   case 7: // 处理结束
    doQuit();
    cont = false;
    break;
   default: // 其他输入
    System.out.println("请选择一个序号");
   }
   return (cont);
}
// main_proc方法
// 输出ftp的命令菜单,调用各种处理方法
public void main_proc() throws IOException {
   boolean cont = true;
   try {
    doLogin();
    while (cont) {
     showMenu();
     cont = execCommand(getCommand());
    }
   } catch (Exception e) {
    System.err.print(e);
    System.exit(1);
   }
}
// getMsgs方法
// 启动从控制流收信的线程
public void getMsgs() {
   try {
    CtrlListen listener = new CtrlListen(ctrlInput);
    Thread listenerthread = new Thread(listener);
    listenerthread.start();
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
// main方法
// 建立TCP连接,开始处理
public static void main(String[] arg) {
  
   try {
    Ftp f = null;
    f = new Ftp();
    f.openConnection("192.168.1.100"); // 控制连接建立,设置为自己的IP.
    f.getMsgs(); // 启动接收线程
    f.main_proc(); // ftp 处理
    f.closeConnection(); // 关闭连接
    System.exit(0); // 结束程序
   } catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
   }
}
}
// 读取控制流的CtrlListen 类
class CtrlListen implements Runnable {
BufferedReader ctrlInput = null;
public CtrlListen(BufferedReader in) {
   ctrlInput = in;
}
public void run() {
   while (true) {
    try {
        // 按行读入并输出到标准输出上
        System.out.println(ctrlInput.readLine());
     } catch (Exception e) {
     System.exit(1);
    }
   }
}
}
    3.运行效果:
   请输入用户名
220 connect success!
rhx
请输入口令
331 Password required for rhx
3468637
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
230 Logged on
1
200 Port command successful
apache-tomcat-6.0.16.exe
c.txt
c37
fc8
FCKeditor
FCKeditor_0.9.2b.zip
FileZilla_3.1.6_win32-setup.exe
ftp.txt
G08-15n.ppt
h
javaftp
javaftp.rar
jftp.jnlp
JSValidation
jsvalidation-1_0b4.zip
other037.rar
photo
ROOT
Tomcat 5.0
trans.rar
transportSystem
Unix澶嶄範棰�.doc
vc863523445
webapps
鍋ュ悍.doc
鏂板缓鏂囨湰鏂囨。.txt
缃戠粶
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
150 Opening data channel for directory list.
226 Transfer OK
2
请输入目录名
javaftp
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
250 CWD successful. "/javaftp" is current directory.
3
远程文件名
ftpClient.java
本地文件
h:/cc.txt
200 Port command successful
150 Opening data channel for file transfer.
226 Transfer OK
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
4
本地文件
h:/cc.txt
远程文件
ftppp.java
200 Port command successful
150 Opening data channel for file transfer.
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
226 Transfer OK
5
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
200 Type set to A
6
>Command?
1:ls 2:cd 3:get 4:put 5:ascii 6:binary 7:quit
200 Type set to I
7

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-228196-1-1.html 上篇帖子: FTP系列:(一)gssftp,vsftp与xinetd的介绍 下篇帖子: 基于Java Swing 的FTP客户端程序
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表