实验内容:

复习Java I/O和Socket编程相关概念和方法;
基于Java Socket TCP和UDP实现一个简易的网络文件服务程序,包含服务器端FileServer和客户端FileClient;
服务器端启动时需传递root目录参数,并校验该目录是否有效;
服务器启动后,开启TCP:2021端口,UDP:2020端口,其中,TCP连接负责与用户交互,UDP负责传送文件;
客户端启动后,连接指定服务器的TCP 2021端口,成功后,服务器端回复信息:“客户端IP地址:客户端端口号>连接成功”;
连接成功后,用户可通过客户端命令行执行以下命令:
[1] ls 服务器返回当前目录文件列表(<file/dir> name size)
[2] cd
进入指定目录(需判断目录是否存在,并给出提示)
[3] get 通过UDP下载指定文件,保存到客户端当前目录下
[4] bye 断开连接,客户端运行完毕
服务器端支持多用户并发访问,不用考虑文件过大或UDP传输不可靠的问题。
实现:
一:

FileClient客户端实现通过TCP向服务器发送命令, 请求相应内容.
具体可以参考服务器端实现

public void send() {
        try {
            SocketAddress socketAddress = new InetSocketAddress(HOST,PORT_TCP);
            //客户端输出流,向服务器发消息
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    socket_TCP.getOutputStream()));
            //客户端输入流,接收服务器消息
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    socket_TCP.getInputStream()));
            PrintWriter pw = new PrintWriter(bw, true); //装饰输出流,及时刷新
            Scanner in = new Scanner(System.in); //接受用户信息
            String msg = null;
            boolean out = false;
            while (((msg = in.nextLine()) != null) && !out) {
                pw.println(msg); //发送给服务器端
                switch (CmdResolution.resolute(msg)){
                    case 0:
                    case 1:
                    case 3:
                    case 2: {
                        TCPReader(br);
                        break;
                    }
                    case 4:{
                       TCPReader(br);
                       DataRecevier();
                       TCPReader(br);
                       break;
                    }
                    case 5:{
                        out = true;
                        break;
                    }
                }
                if (msg.equals("bye")) {
                   break; //退出
               }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != socket_TCP) {
                try {
                    socket_TCP.close(); //断开连接
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

TCPReader函数用于解析服务器返回的字符串

public void TCPReader(BufferedReader br) throws IOException {
        String info;
        while (null != (info = br.readLine())){
            if(info.equals("...")){
                break;
            }
            System.out.println(info); //输出服务器返回的消息
        }
    }

DataRecevier类似服务器端的FileSender函数不再赘述

 public void DataRecevier() throws IOException {
            SocketAddress socketAddress = new InetSocketAddress(HOST,PORT_UDP);
            DatagramPacket very = new DatagramPacket(new byte[2], 2,socketAddress);
            very.setData(("OK").getBytes());
            socket_UDP.send(very);
            DatagramPacket fileLen = new DatagramPacket(new byte[8],8);
            socket_UDP.receive(fileLen);
            String msg = new String(fileLen.getData(),0, fileLen.getLength());
            System.out.println(msg);

            UDPFileReceiver server = new UDPFileReceiver(socket_UDP,1024);
            server.receiveFile();
            System.out.println("收到文件:"+ server.getFileName());
            File file = new File(server.getFileName());
            FileOutputStream fo = new FileOutputStream(file);
            fo.write(server.getFileData());
            fo.close();
            server.close();
    }

客户端代码