socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)

Posted 你好,旧时光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)相关的知识,希望对你有一定的参考价值。

通过socket实现两台FTP服务器指定目录下的文件转移,其中包含了基础了ftp文件列表显示、上传和下载。这里仅供学习用,需掌握的点有socket、ftp命令、文件流读取转换等

完整代码如下:

FtpFileTransfer.java

package com.xxx.ftp.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import com.xxx.ftp.model.ConnectInfo;
import com.xxx.ftp.model.FtpServerInfo;

public class FtpFileTransfer {

    /**
     * 文件转移
     * 
     * @param source
     *            源ftp文件目录
     * @param dest
     *            目标ftp文件目录
     * @throws IOException
     */
    public void transfer(FtpServerInfo source, FtpServerInfo dest) throws IOException {
        // 源ftp目录下的文件列表
        sendCommand(source.getConnect(), "CWD " + source.getDir());
        sendCommand(source.getConnect(), "PASV");
        String response = readNewMessage(source.getConnect());
        String[] ipPort = getIPPort(response);

        String ip = ipPort[0];
        int port = Integer.valueOf(ipPort[1]);
        Socket dataSocket = new Socket(ip, port);
        sendCommand(source.getConnect(), "LIST");

        BufferedReader br = new BufferedReader(new InputStreamReader(dataSocket.getInputStream()));
        // 读取源服务器的目录下所有文件名称
        List<String> fileNameList = new ArrayList<String>();
        String s = "";
        while ((s = br.readLine()) != null) {
            String fileInfo = new String(s.getBytes("ISO-8859-1"), "utf-8");
            String[] arr = fileInfo.split("\s+");
            String fileName = arr[arr.length - 1];
            fileNameList.add(fileName);
            System.out.println(fileName);
        }

        if (fileNameList.size() > 0) {
            for (Iterator iterator = fileNameList.iterator(); iterator.hasNext();) {
                // 根据文件名获取文件流
                String fileName = (String) iterator.next();
                sendCommand(source.getConnect(), "PASV");
                response = readNewMessage(source.getConnect());
                ipPort = getIPPort(response);
                ip = ipPort[0];
                port = Integer.valueOf(ipPort[1]);
                Socket sourceDataSocket = new Socket(ip, port);
                sendCommand(source.getConnect(), "RETR " + source.getDir() + "/" + fileName);
                InputStream inputStream = sourceDataSocket.getInputStream();

                // 文件流通过socket传输至目标ftp服务器文件目录
                sendCommand(dest.getConnect(), "PASV");
                response = readNewMessage(dest.getConnect());
                ipPort = getIPPort(response);
                ip = ipPort[0];
                port = Integer.valueOf(ipPort[1]);
                Socket destDataSocket = new Socket(ip, port);
                sendCommand(dest.getConnect(), "STOR " + dest.getDir() + "/" + fileName);
                OutputStream outputStream = destDataSocket.getOutputStream();

                int offset;
                byte[] bytes = new byte[1024];
                while ((offset = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, offset);
                }
                inputStream.close();
                outputStream.close();
                dataSocket.close();
            }
        }

        System.out.println("transfer success!");

    }

    /**
     * ftp服务器连接
     * 
     * @param ftpServerInfo
     *            ftp服务器信息 包含用户名 密码
     * @return
     * @throws IOException
     */
    public ConnectInfo connect(FtpServerInfo ftpServerInfo) throws IOException {
        Socket socket = new Socket(ftpServerInfo.getHost(), ftpServerInfo.getPort());
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        ConnectInfo connectInfo = new ConnectInfo();
        connectInfo.setSocket(socket);
        connectInfo.setWriter(writer);
        connectInfo.setReader(reader);

        sendCommand(connectInfo, "USER " + ftpServerInfo.getUser());
        sendCommand(connectInfo, "PASS " + ftpServerInfo.getPass());
        return connectInfo;
    }

    /**
     * 断开ftp服务器连接
     * 
     * @param connectInfo
     * @throws IOException
     */
    public void disconnect(ConnectInfo connectInfo) throws IOException {
        if (connectInfo.getSocket() == null || !connectInfo.getSocket().isConnected()) {
            return;
        }
        connectInfo.getSocket().close();
    }

    /**
     * 发送ftp命令
     * 
     * @param connectInfo
     *            ftp服务器连接信息
     * @param command
     *            ftp命令
     * @throws IOException
     */
    private void sendCommand(ConnectInfo connectInfo, String command) throws IOException {
        if (command == null || command == "") {
            return;
        }
        connectInfo.getWriter().write(command + "
");
        connectInfo.getWriter().flush();
    }

    /**
     * 根据连接读取ftp信息
     * 
     * @param connect
     * @return
     * @throws IOException
     */
    private String readNewMessage(ConnectInfo connect) throws IOException {
        String response = null;
        while (true) {
            response = connect.getReader().readLine();
            if (response == null || response.length() == 0) {
                return null;
            }
            String rexp = "Entering Passive Mode";
            if (response.contains(rexp)) {
                break;
            }
        }
        return response;
    }

    /**
     * 获取ip和端口
     * 
     * @param response
     * @return
     * @throws IOException
     */
    private String[] getIPPort(String response) throws IOException {
        String[] ret = new String[2];
        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);
            }
        }
        ret[0] = ip;
        ret[1] = String.valueOf(port);
        return ret;
    }

    public static void main(String[] args) throws IOException {
        FtpFileTransfer ft = new FtpFileTransfer();

        // 源ftp服务器
        FtpServerInfo source = new FtpServerInfo();
        source.setHost("192.168.11.129");
        source.setUser("haoxr");
        source.setPass("123456");
        source.setDir("/home/haoxr/test");
        ConnectInfo sourceConnectInfo = ft.connect(source);
        source.setConnect(sourceConnectInfo);

        // 目标ftp服务器
        FtpServerInfo dest = new FtpServerInfo();
        dest.setHost("192.168.11.130");
        dest.setUser("haoxr");
        dest.setPass("123456");
        dest.setDir("/home/haoxr/test");
        ConnectInfo destConnectInfo = ft.connect(dest);
        dest.setConnect(destConnectInfo);

        // 文件转移
        ft.transfer(source, dest);
        ft.disconnect(sourceConnectInfo);
        ft.disconnect(destConnectInfo);
    }

}

ConnectInfo.java    (javabean)

技术分享图片
package com.xxx.ftp.model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.net.Socket;

public class ConnectInfo {

    private Socket socket;
    private BufferedReader reader;
    private BufferedWriter writer;

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public BufferedReader getReader() {
        return reader;
    }

    public void setReader(BufferedReader reader) {
        this.reader = reader;
    }

    public BufferedWriter getWriter() {
        return writer;
    }

    public void setWriter(BufferedWriter writer) {
        this.writer = writer;
    }
    
    

}
View Code

FtpServerInfo.java  (javabean)

技术分享图片
package com.xxx.ftp.model;

public class FtpServerInfo {

    public FtpServerInfo() {
        this.port = 21;
    }

    private String host;
    private int port;
    private String user;
    private String pass;

    private ConnectInfo connect;

    public ConnectInfo getConnect() {
        return connect;
    }

    public void setConnect(ConnectInfo connect) {
        this.connect = connect;
    }

    /** 文件目录 */
    String dir;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public String getDir() {
        return dir;
    }

    public void setDir(String file) {
        this.dir = file;
    }
    
    public static void main(String[] args) {
        FtpServerInfo fs=new FtpServerInfo();
        String pass=fs.getPass();
        System.out.println(pass);
        
        fs=new FtpServerInfo();
        fs.setPass("123456");
        pass=fs.getPass();
        
        System.out.println(pass);
    }

}
View Code

 

以上是关于socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)的主要内容,如果未能解决你的问题,请参考以下文章

如何通过socket编程在两台机器之间发送文件?

JavaFTP递归查询指定目录下的所有目录和文件

Python操作FTP服务器实现文件和文件夹的上传与下载,python清理ftp目录下的所有文件和非空文件夹

ftp实现终端start,并且反射型命令分发

怎么使用FTP实现两台计算机之间文件的传输?需要注意啥?

php 如何通过连接sftp并下载sftp服务器指定目录下的所有文件到本地?