使用socket编程实现一个简单的文件服务器

使用socket编程实现一个简单的文件服务器。客户端程序实现put功能(将一个文件从本地传到文件服务器)get功能(从文件服务器取一远程文件存为本地文件)。客户端和文件服务器不在同一台机器上。
put [-h hostname] [-p portname] local_filenameremote_filename
get [-h hostname] [-p portname] remote_filenamelocal_filename
程序如下:

客户端Client.java

package com.cn.gao;
import java.net.*;
import java.io.*;
/**
 * 
 * 用Socket实现文件服务器的客户端
 * 包含发送文件和接收文件功能
 *
 */
public class Client {
    private Socket client;
    private boolean connected;
    //构造方法
    public Client(String host,int port){
            try {
                //创建Socket对象
                client = new Socket(host,port);
                System.out.println("服务器连接成功!");
                this.connected = true;
            } catch (UnknownHostException e) {
                System.out.println("无法解析的主机!");
                this.connected = false;
            } catch (IOException e) {
                System.out.println("服务器连接失败!");
                this.connected = false;
                closeSocket();
            }        
    }
    //判断是否连接成功
    public boolean isConnected(){
        return connected;
    }
    //设置连接状态
    public void setConnected(boolean connected){
        this.connected = connected;
    }
    /**
     * 发送文件方法
     * @param localFileName 本地文件的全路径名
     * @param remoteFileName 远程文件的名称
     */
    public void sendFile(String localFileName, String remoteFileName){
        DataOutputStream dos = null; //写Socket的输出流
        DataInputStream dis = null;  //读取本地文件的输入流
        if(client==null) return;
        File file = new File(localFileName);
        //检查文件是否存在
        if(!file.exists()){
            System.out.println("本地文件不存在,请查看文件名是否写错!");
            this.connected = false;
            this.closeSocket();
            return;
        }
        try {
            //初始化本地文件读取流
            dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            //将指令和文件发送到Socket的输出流中
            dos = new DataOutputStream(client.getOutputStream());
            //将远程文件名发送出去
//            System.out.println(remoteFileName);
            dos.writeUTF("put "+remoteFileName);
            //清空缓存,将文件名发送出去
            dos.flush();
            //开始发送文件
            int bufferSize = 10240;
            byte[] buf = new byte[bufferSize];
            int num =0;
            while((num=dis.read(buf))!=-1){
                dos.write(buf, 0, num);
            }
            dos.flush();
            System.out.println("文件发送成功!");
        } catch (IOException e) {
            System.out.println("文件传输错误!");
            closeSocket();
        } finally{
            try {
                dis.close();
                dos.close();
            } catch (IOException e) {
                System.out.println("输入输出错误!");
            }
        }
    }
    /**
     * 接收文件方法
     * @param remoteFileName 本地文件的全路径名
     * @param localFileName  远程文件的名称
     */
    public void receiveFile(String remoteFileName, String localFileName){
        DataOutputStream dos = null; //写Scoket的输出流
        DataInputStream dis = null;  //读Socket的输入流
        DataOutputStream localdos = null; //写本地文件的输出流
        if(client==null) return;
        try {
            localdos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(localFileName)));
            //将指令和文件名发送到Socket的输出流中
            dos = new DataOutputStream(client.getOutputStream());
            //将远程文件名发送出去
            dos.writeUTF("get "+remoteFileName);
            dos.flush();
            //开始接收文件
            dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
            int bufferSize = 10240;
            byte[] buf = new byte[bufferSize];
            int num = 0;
            while((num=dis.read(buf))!=-1){
                localdos.write(buf, 0, num);
            }
            localdos.flush();
            System.out.println("数据接收成功!");
        } catch (FileNotFoundException e) {
            System.out.println("文件没有找到!");
            closeSocket();
        } catch (IOException e) {
            System.out.println("文件传输错误!");
        } finally {
            try {
                dos.close();
                localdos.close();
                dis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //关闭端口
    public void closeSocket(){
        if(client!=null){
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 主方法调用上述方法
     * @param args
     * 将本地文件上传到远程服务器
     * put[-h hostname][-p portname]local_filename remote_filename
     * 从远程服务器上下载文件
     * get[-h hostname][-p portname]remote_filename local_filename
     */
    public static void main(String[] args){
        //服务器默认端口为8888
        if(args.length!=7){
            System.out.println("参数数目不正确!");
            return;
        }
        String hostName = args[2];
        int port = 0;
        String localFileName = "";
        String remoteFileName = "";
        Client client = null;
        try {
            port = Integer.parseInt(args[4]);
        } catch (NumberFormatException e) {
            System.out.println("端口号输出格式错误!");
            return;
        }
        if(args[0].equals("put")){
            //上传文件
            client = new Client(hostName,port);
            localFileName = args[5];
            remoteFileName = args[6];
//            System.out.println(remoteFileName);
            if(client.isConnected()){
                client.sendFile(localFileName, remoteFileName);
                client.closeSocket();
            }
        }else if(args[0].equals("get")){
            //下载文件
            client = new Client(hostName,port);
            localFileName = args[6];
            remoteFileName = args[5];
            if(client.isConnected()){
                client.receiveFile(remoteFileName, localFileName);
                client.closeSocket();
            }
        }else{
            System.out.println("命令输入不正确,正确命令格式如下:");
            System.out.println("put -h hostname -p portname local_filename remote_filename");
            System.out.println("get -h hostname -p portname remote_filename local_filename");
        }
    }
}

服务器端Server.java

package com.cn.gao;
import java.io.*;
import java.net.*;
/**
 * 实现服务器端
 * 用于接收上传的数据和供客户端下载数据
 * @author DELL
 *
 */
public class Server {
    private int port;
    private String host;
    private String dirPath;
    private static ServerSocket server;
    
    public Server(int port,String dirPath){
        this.port = port;
        this.dirPath = dirPath;
        this.server = null;
    }
    
    public void run(){
        if(server==null){
            try {
                server = new ServerSocket(port);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("服务已启动...");
        while(true){
            try {
                //通过ServerSocket的accept方法建立连接,并获取客户端的Socket对象
                Socket client = server.accept();
                if(client==null) continue;
                new SocketConnection(client,this.dirPath).run();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    /**
     * 实现服务器端的数据传输
     * @author DELL
     *
     */
    public class SocketConnection extends Thread{
        private Socket client;
        private String filePath;
        
        public SocketConnection(Socket client, String filePath){
            this.client = client;
            this.filePath = filePath;
        }
        
        public void run(){
            if(client==null) return;
            DataInputStream in= null; //读取Socket的输入流
            DataOutputStream dos = null; //写文件的输出流
            DataOutputStream out = null; //写Socket的输出流
            DataInputStream dis = null; //读文件的输入流
            try {
                //访问Scoket对象的getInputStream方法取得客户端发送过来的数据流
                in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
                String recvInfo = in.readUTF(); //取得附带的指令及文件名
//                System.out.println(recvInfo);
                String[] info = recvInfo.split(" ");
                String fileName = info[1]; //获取文件名
//                System.out.println(fileName);
                if(filePath.endsWith("/")==false&&filePath.endsWith("\")==false){
                    filePath+="\";
                }
                filePath += fileName;
                if(info[0].equals("put")){
                    //从客户端上传到服务器
                    //开始接收文件
                    dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(filePath))));
                    int bufferSize = 10240;
                    byte[] buf = new byte[bufferSize];
                    int num =0;
                    while((num=in.read(buf))!=-1){
                        dos.write(buf, 0, num);
                    }
                    dos.flush();
                    System.out.println("数据接收完毕!");
                }else if(info[0].equals("get")){
                    //从服务器下载文件到客户端
                    dis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
                    //开始发送文件
                    int bufferSize = 10240;
                    byte[] buf = new byte[bufferSize];
                    out = new DataOutputStream(client.getOutputStream());
                    int num =0;
                    while((num=dis.read(buf))!=-1){
                        out.write(buf, 0, num);
                    }
                    out.flush();
                    System.out.println("发送成功!");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                try {
                    if(out!=null) out.close();
                    if(in!=null)  in.close();
                    if(dos!=null) dos.close();
                    if(dis!=null) dis.close();
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args){
        //设置服务器端口
        int port = 8888;
        //设置服务器文件存放位置
        String dirPath = "D:\FTPService\";
        new Server(port,dirPath).run();
    }
}

参数输入方式示例

put -h 127.0.0.1 -p 8888 D:\data.xls data.xls

get -h 127.0.0.1 -p 8888 data.xls D:\data.xls

原文地址:https://www.cnblogs.com/gaopeng527/p/4414705.html