2021-10-28

java实现多线程FTP服务器(多客户端进行上传下载)

在csdn上看了很多都感觉不是很适合学习,所以将自己的实现代发出来供大家参考,可以一起讨论

//server端
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

public class FTPServer {
    private static Vector<Socket> sockets = new Vector<>();
    public static void main(String[] args) {
        System.out.println("FTP服务器启动...");
        ServerSocket serverSocket = null;
//      创建服务器
        try {
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (true){
            try {
                Socket accept = serverSocket.accept();
                sockets.add(accept);
                new TransHandler(accept).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 *  处理客户端请求
 */
class TransHandler extends Thread{
    //客户端的socket
    private Socket m_clientSocket;
    //从客户端传来的指令
    String command;
    //用于得到从socket端的输入信息
    DataInputStream m_dataInputStream;
    //用于向socket输出的输出流
    DataOutputStream m_dataOutputStream;
    //客户端的地址和端口
    InetAddress inetAddress ;
    int port ;
    //客户端下载地址
    String serverDir = "C:\\Users\\Angus\\Desktop\\FTPServerDir\\";

    public TransHandler(Socket accept) {
        //客户端的socket
        m_clientSocket = accept;
        inetAddress = accept.getInetAddress();
        port = accept.getPort();
        try {
            m_dataInputStream = new DataInputStream(accept.getInputStream());
            m_dataOutputStream = new DataOutputStream(accept.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            System.out.println(inetAddress+":\\"+ port+"连接成功");
            while(true){
                if (m_clientSocket.isConnected()){
                    command = m_dataInputStream.readUTF();
                    if (command.startsWith("put ")){
                        receive(command.substring(4),m_dataInputStream);
                    }else if (command.startsWith("get ")){
                        send(command.substring(4),m_dataOutputStream);
                    }else if (command.equals("disconnect")){
                        System.out.println(port+"已退出连接");
                        break;
                    }
                }
            }
        }catch (Exception e){
            System.out.println(port+"客户端异常退出");
        }finally {
            try {
                m_dataInputStream.close();
                m_dataOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void receive(String filename, DataInputStream dis){
        try {
            long size = dis.readLong();
            FileOutputStream fileOutputStream = new FileOutputStream(serverDir + filename);
            for (long i = 0; i < size; i++){
                fileOutputStream.write(dis.read());
            }
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件传输失败");
        }
        System.out.println("文件接收成功");
    }

    public void send(String filename, DataOutputStream dos){
        FileInputStream fileInputStream = null;
        try {
            File file = new File(serverDir + filename);
            if (!file.exists()){
                dos.writeBoolean(false);
            }else {
                dos.writeBoolean(true);
                long size = file.length();
                dos.writeLong(size);
                fileInputStream = new FileInputStream(file);
                for (long i=0;i<size;i++){
                    dos.write(fileInputStream.read());
                }
                fileInputStream.close();
                System.out.println("文件发送成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件发送失败");
        }
    }
}
//Client端

import java.io.*;
import java.net.ConnectException;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class FTPClientThread extends Thread{
    private String host = "127.0.0.1";
    private int port = 8888;

    /**
     * 使用默认属性
     */
    public FTPClientThread() {
    }
    /**	  可有可无
     * @param host : 指定服务器地址
     * @param port : 指定服务端端口
     */
    public FTPClientThread(String host, int port) {
        this.host = host;
        this.port = port;
    }
    private boolean connected = false;
    private Socket socket = null;
    private DataInputStream dataInputStream = null;
    private DataOutputStream dataOutputStream = null;
    private String localDir = "C:\\Users\\Angus\\Desktop\\FTPServerDir\\download\\";
    private String threadName = Thread.currentThread().getName();


    @Override
    public void run() {
        System.out.println("FTP Client启动...");
        connect();
        String command = null;
        while (true) {
            System.out.print("ftp:\\>");
            Scanner scanner = new Scanner(System.in);
            command = scanner.nextLine();
            if (command.startsWith("put ")){
                put(command.substring(4));
            }else if (command.startsWith("get ")){
                get(command.substring(4));
            }else if (command.equals("exit")){
                break;
            }else {
                System.out.println("无效指令,请重试!");
            }
        }
        disconnect();
    }

    public void connect(){
        try {
            Socket socket = new Socket(host,port);
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            System.out.println("FTP服务器连接成功...");
            connected = true;
        } catch (ConnectException e) {
            System.out.println("连接FTP服务器失败...正在重新连接...");
            connect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void put(String localFile){
        try {
            File file = new File(localFile);
            if (file.exists()){
                long size = file.length();
                dataOutputStream.writeUTF("put "+file.getName());
                dataOutputStream.writeLong(size);
                FileInputStream fileInputStream = new FileInputStream(localFile);
                for (long i=0;i<size;i++){
                    dataOutputStream.write(fileInputStream.read());
                }
                fileInputStream.close();
                System.out.println("文件上传成功!");
            }else {
                System.out.println("文件不存在,上传失败!");
            }
        } catch (IOException e) {
            System.out.println("文件上传失败!");
        }
    }

    public void get(String remoteFile){
        try {
            dataOutputStream.writeUTF("get "+remoteFile);
            boolean exist = dataInputStream.readBoolean();
            if (exist){
                long size = dataInputStream.readLong();
                FileOutputStream fileOutputStream = new FileOutputStream(localDir + remoteFile,true);
                for (long i = 0; i < size; i++) {
                    fileOutputStream.write(dataInputStream.read());
                }

                fileOutputStream.close();
                System.out.println("下载文件成功!");
            }else {
                System.out.println("请求的文件不存在,请重新输入指令!");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("下载文件失败!");
        }
    }

    public void disconnect(){
        if (connected){
            try {
                dataOutputStream.writeUTF("disconnect");
                dataInputStream.close();
                dataOutputStream.close();
                if (socket!=null){
                    socket.close();
                }
                connected = false;
                System.out.print("程序退出.");
            } catch (SocketException e) {
                System.out.print("网络连接异常,程序退出!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

//测试程序
public class FTPClientTest {
    public static void main(String[] args) {
        FTPClientThread ftpClientThread1 = new FTPClientThread();
        ftpClientThread1.setName("客户端1");
        ftpClientThread1.start();
        
		FTPClientThread ftpClientThread2 = new FTPClientThread();
        ftpClientThread2.setName("客户端2");
        ftpClientThread2.start();
    }
}

转载请注明出处

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值