zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    Selenium 中ExpectedConditions 用法说明(最全整理)
    logback的使用和logback.xml详解
    彻底征服 Spring AOP 之 实战篇
    彻底征服 Spring AOP 之 理论篇
    面试
    Java面试
    Python的数据类型与数据结构
    利用Python的 counter内置函数,统计文本中的单词数量
    python爬虫Urllib实战
    python爬虫实战一(基于正则表达式学习)
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4414705.html
Copyright © 2011-2022 走看看