TCP服务器和客户端学生管理系统(第二天)完整版

TCP服务器和客户端学生管理系统(第二天)完整版

一,工具类(util包中)

1.1 客户端用户操作枚举

package com.qfedu.student.system.client.util;

/**
 * @author Anonymous 2020/3/18 11:39
 */
public enum ClientOperation {
    /**
     * 用户操作枚举
     */
    FIND_ALL(1, "findAll"),
    FIND_ONE(2, "findOne"),
    ADD(3, "addStudent"),
    MODIFY(4, "modifyStudent"),
    REMOVE(5, "removeStudent"),
    SORT_STU(6, "sortStu"),
    FILTER_STU(7, "filterStu"),
    LOGOUT(8, "logout");


    private int id;
    private String methodName;

    ClientOperation() {
    }

    ClientOperation(int id, String methodName) {
        this.id = id;
        this.methodName = methodName;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }
}

1.2 服务端排序方法工具类

package com.qfedu.student.system.server.util;

import com.qfedu.student.system.server.entity.Student;

/**
 * @author Anonymous 2020/3/18 16:05
 */
public class SortMethodUtil {
    public static int ageAsc(Student stu1, Student stu2) {
        return stu1.getAge() - stu2.getAge();
    }

    public static int ageDesc(Student stu1, Student stu2) {
        return stu2.getAge() - stu1.getAge();
    }

    public static int mathScoreAsc(Student stu1, Student stu2) {
        return stu1.getMathScore() - stu2.getMathScore();
    }

    public static int mathScoreDesc(Student stu1, Student stu2) {
        return stu2.getMathScore() - stu1.getMathScore();
    }

    public static int chnScoreAsc(Student stu1, Student stu2) {
        return stu1.getChnScore() - stu2.getChnScore();
    }

    public static int chnScoreDesc(Student stu1, Student stu2) {
        return stu2.getChnScore() - stu1.getChnScore();
    }

    public static int engScoreAsc(Student stu1, Student stu2) {
        return stu1.getEngScore() - stu2.getEngScore();
    }

    public static int engScoreDesc(Student stu1, Student stu2) {
        return stu2.getEngScore() - stu1.getEngScore();
    }

    public static int totalScoreAsc(Student stu1, Student stu2) {
        return stu1.getTotalScore() - stu2.getTotalScore();
    }

    public static int totalScoreDesc(Student stu1, Student stu2) {
        return stu2.getTotalScore() - stu1.getTotalScore();
    }

}

二,服务端

2.1 服务器数据处理中转站(controller包中)

package com.qfedu.student.system.server.controller;

import com.qfedu.student.system.server.service.StudentService;
import com.qfedu.student.system.server.tcp.ServerTcp;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.channels.SelectionKey;

/**
 * 服务器数据处理中转站
 *
 * @author Anonymous 2020/3/18 15:04
 */
public class ServerController {

    private static StudentService service = new StudentService();


    /**
     * 处理客户端发送数据,调用执行StudentDao层方法
     *
     * @param server ServerTcp服务器对象
     * @param key SelectionKey 对应当前客户端发送数据SocketChannel
     * @param message 客户端发送的请求
     */
    public static void processingData(ServerTcp server,SelectionKey key, String message)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<StudentService> cls = StudentService.class;
        String sendMsg = null;

        // addStu:JsonString
        String methodName = message.substring(0, message.indexOf(":"));
        message = message.substring(message.indexOf(":") + 1);

        // 执行close方法
        if ("close".equals(methodName)) {
            Method method = cls.getMethod(methodName, SelectionKey.class);
            method.invoke(service, key);

            // 终止当前方法
            return;

        } else if ("findAll".equals(methodName)) {
            // 执行findAll方法
            Method method = cls.getMethod(methodName);
            sendMsg = (String) method.invoke(service);
        } else {
            // 执行其他功能方法
            Method method = cls.getMethod(methodName, String.class);
            sendMsg = (String) method.invoke(service, message);
        }

        server.sendMessage(key, sendMsg);
    }
}

2.2 服务层(service包中)

package com.qfedu.student.system.server.service;

import com.qfedu.student.system.server.dao.StudentDao;
import com.qfedu.student.system.server.entity.Student;
import com.qfedu.student.system.server.util.JsonUtil;
import com.qfedu.student.system.server.util.SortMethodUtil;

import java.lang.reflect.Method;
import java.nio.channels.SelectionKey;
import java.util.ArrayList;
import java.util.List;

/**
 * StudentService服务层
 *
 * @author Anonymous 2020/3/18 15:14
 */
public class StudentService {

    /**
     * StudentService保存一个计数器,一会儿保存到文件中
     */
    private static int count = 1;

    static {
        // 读取文件,修改count
    }

    /**
     * StudentDao层,数据控制层
     */
    private StudentDao dao = StudentDao.getInstance();

    private final static String OP_SUCCESS = "操作成功";
    private final static String OP_FAILED = "操作失败";
    private final static String NOT_FOUND = "查无此人";
    private final static String EMPTY_SET = "无数据";

    /**
     * 登陆验证方法
     *
     * @param message 带有用户名和密码的字符串
     * @return 登陆验证消息
     */
    public String login(String message) {
        String[] split = message.split(":");

        if ("骚磊".equals(split[0]) && "123456".equals(split[1])) {
            return "success";
        } else {
            return "failed";
        }
    }

    /**
     * 添加学生的方法
     *
     * @param message 客户端发送过来的带有学生信息的Json格式字符串
     * @return 添加状态信息
     */
    public String addStu(String message) {

        Student student = JsonUtil.jsonToStudent(message);
        student.setId(count++);

        boolean ret = dao.add(student);

        return ret ? OP_SUCCESS : OP_FAILED;
    }

    /**
     * 删除学生的方法
     *
     * @param message 需要删除学生的ID信息字符串
     * @return 操作状态
     */
    public String deleteStu(String message) {
        int id = Integer.parseInt(message);

        Student remove = dao.remove(id);

        return remove != null ? OP_SUCCESS : OP_FAILED;
    }

    /**
     * 修改指定学生信息方法
     *
     * @param message 客户端发送的需要修改信息对应Student Json格式字符串
     * @return 操作状态
     */
    public String modifyStu(String message) {
        Student student = JsonUtil.jsonToStudent(message);
        Integer id = student.getId();
        dao.modifyStudent(id, student);

        return OP_SUCCESS;
    }

    /**
     * 查询对应ID的学生
     *
     * @param message 指定学生ID信息字符串
     * @return 找到对应学生,返回当前Student信息对应的Json格式字符串,没有找到返回NOT_FOUND
     */
    public String findOne(String message) {
        int id = Integer.parseInt(message);
        Student student = dao.getStudentById(id);

        return student != null ? JsonUtil.studentToJson(student) : NOT_FOUND;
    }

    /**
     * 返回所有所有学生信息Json格式字符串
     *
     * @return 如果存在学生信息,返回Json格式字符串,没有返回EMPTY_SET
     */
    public String findAll() {
        ArrayList<Student> list = dao.getAllStudents();

        return list.size() != 0 ? JsonUtil.studentListToJson(list) : EMPTY_SET;
    }

    /**
     * 按照客户端指定的消息进行数据过程
     *
     * @param message 带有age消息要求的字符串 min,max 例如: 10,20
     * @return 返回过滤之后的学生信息List集合对应Json各种字符串,如果没有数据发,返回EMPTY_SET
     */
    public String filterStu(String message) {
        String[] split = message.split(",");

        int min = Integer.parseInt(split[0]);
        int max = Integer.parseInt(split[1]);

        List<Student> list = dao.filter(student -> student.getAge() >= min && student.getAge() <= max);

        return list != null ? JsonUtil.studentListToJson(list) : EMPTY_SET;
    }

    @SuppressWarnings("all")
    public String sortStu(String message) {
        List<Student> list = null;

        switch (message) {
            // 方法引用 类名操作方法引用
            case "1":
                list = dao.sortUsingCompara(SortMethodUtil::ageAsc);
                break;
            case "2":
                list = dao.sortUsingCompara(SortMethodUtil::ageDesc);
                break;
            case "3":
                list = dao.sortUsingCompara(SortMethodUtil::mathScoreAsc);
                break;
            case "4":
                list = dao.sortUsingCompara(SortMethodUtil::mathScoreDesc);
                break;
            case "5":
                list = dao.sortUsingCompara(SortMethodUtil::chnScoreAsc);
                break;
            case "6":
                list = dao.sortUsingCompara(SortMethodUtil::chnScoreDesc);
                break;
            case "7":
                list = dao.sortUsingCompara(SortMethodUtil::engScoreAsc);
                break;
            case "8":
                list = dao.sortUsingCompara(SortMethodUtil::engScoreDesc);
                break;
            case "9":
                list = dao.sortUsingCompara(SortMethodUtil::totalScoreAsc);
                break;
            case "10":
                list = dao.sortUsingCompara(SortMethodUtil::totalScoreDesc);
                break;
            default:
                break;
        }

        return list.size() != 0 ? JsonUtil.studentListToJson(list) : EMPTY_SET;
    }

    /**
     * 断开服务器和客户端连接
     *
     * @param key 需要关闭的对应客户端连接的SelectionKey
     */
    public void close(SelectionKey key) {
        key.cancel();
    }
}

2.3 服务器TCP NIO连接客户端,注册客户端连接,发送消息,接收消息(tcp包中)

package com.qfedu.student.system.server.tcp;

import com.qfedu.student.system.server.controller.ServerController;
import com.qfedu.student.system.server.dao.StudentDao;
import com.qfedu.student.system.server.util.JsonUtil;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * 服务器TCP NIO连接客户端,注册客户端连接,发送消息,接收消息
 *
 * @author Anonymous 2020/3/17 14:33
 */
public class ServerTcp {

    /**
     * ServerSocketChannel对象,提供服务的核心
     */
    private ServerSocketChannel serverSocket;

    /**
     * 选择器对象,需要注册到ServerSocketChannel
     */
    private Selector selector;

    /**
     * 当前服务需要监听的端口号
     */
    private static final int PORT = 8848;

    /**
     * ServerTcp构造方法,启动ServerSocketChannel服务
     */
    public ServerTcp() {
        try {
            // 开启ServerSocket服务器
            serverSocket = ServerSocketChannel.open();
            // 开启选择器,大哥
            selector = Selector.open();
            // 绑定监听的端口
            serverSocket.bind(new InetSocketAddress(PORT));
            // 设置当前ServerSocketChannel为非阻塞IO
            serverSocket.configureBlocking(false);
            // 注册ServerSocketChannel,当前监听事件为SelectionKey.OP_ACCEPT
            serverSocket.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 服务器核心方法,需要不断监听对应的端口,已经事件
     */
    public void start() {
        while (true) {
            try {
                // 保存监听连接状态
                if (0 == selector.select(2000)) {
                    continue;
                }

                // 获取当前所有相应的selectKey
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                // 得到对应SelectionKey Set集合迭代器对象
                Iterator<SelectionKey> iterator = selectionKeys.iterator();

                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();

                    // 请求连接状态
                    if (key.isAcceptable()) {
                        SocketChannel socket = serverSocket.accept();
                        socket.configureBlocking(false);
                        socket.register(selector, SelectionKey.OP_READ);
                    }

                    // socket发送数据到服务器
                    if (key.isReadable()) {
                        // 读取数据
                        receiveMessage(key);
                    }

                    iterator.remove();
                }


            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 接收数据的方法,需要的参数是SelectionKey
     *
     * @param key 对应当前SelectionKey接收数据
     */
    public void receiveMessage(SelectionKey key) {
        SocketChannel channel = (SocketChannel) key.channel();

        int length = -1;
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        StringBuilder stb = new StringBuilder();
        try {
            while ((length = channel.read(buffer)) > 0) {
                stb.append(new String(buffer.array(), 0, length));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        String s = stb.toString();
        // 处理对应的功能,Controller
        try {
            ServerController.processingData(this, key, s);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 发送数据
     *
     * @param key     对应当前客户端请求的SelectionKey对象
     * @param message 需要发送的字符串数据
     */
    public void sendMessage(SelectionKey key, String message) {

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        SocketChannel channel = (SocketChannel) key.channel();

        ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());

        try {
            channel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        StudentDao dao = StudentDao.getInstance();
        JsonUtil.readDataFromJsonFile(dao);

        Thread thread = new Thread(() -> {
            try {

                while (true) {
                    Thread.sleep(1000 * 5);
                    JsonUtil.saveDataToJsonFile(dao);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread.setDaemon(true);
        thread.start();

        new ServerTcp().start();
    }
}

三,客户端

3.1 客户端控制层 客户端功能 <> 数据交互 <> 服务器(controller包中)

package com.qfedu.student.system.client.controller;

import com.qfedu.student.system.client.service.ClientService;
import com.qfedu.student.system.client.tcp.ClientTcp;

/**
 * 客户端控制层
 *      客户端功能 <==> 数据交互 <==> 服务器
 *
 * @author Anonymous 2020/3/17 15:23
 */
public class ClientController {

    /**
     * 客户端服务层对象,提供客户端操作
     */
    private ClientService service = new ClientService();

    /**
     * TCP服务器客户端连接对象
     */
    private ClientTcp client = new ClientTcp();

    /**
     * 成功信息
     */
    private static final String SUCCESS = "success";

    /**
     * 查无此人
     */
    private static final String NOT_FOUND = "查无此人";
    private final static String EMPTY_SET = "无数据";

    /**
     * 用户登陆方法,登陆成功,继续操作,登陆失败,关闭客户端,断开
     * 服务器连接,销毁socket
     */
    public void login() {
        String s = service.loginMessage();

        client.sendMessage("login:" + s);

        String s1 = client.receiveMessage();

        if (SUCCESS.equals(s1)) {
            System.out.println("登陆成功");
        } else {
            System.out.println("登陆失败");
            logout();
        }
    }

    /**
     * 客户端退出
     */
    public void logout() {
        // 断开连接
        client.sendMessage("close:");
        // 终止程序
        System.exit(0);
    }

    /**
     * 客户端Add方法
     */
    public void addStudent() {
        // 从客户端功能中呼气一个Student数据对应的JsonString
        String studentJsonString = service.getStudent();

        // 服务器执行的方法 addStudent方法 String
        // 服务器端 addStudent(String jsonString)
        // addStudent:{"age":16,"chnScore":100,"engScore":100,"gender":false,"id":1,"mathScore":100,"name":"骚磊","rank":1,"totalScore":300}
        String message = "addStu:" + studentJsonString;

        // 发送数据给服务器
        client.sendMessage(message);

        String s = client.receiveMessage();

        System.out.println(s);
    }

    /**
     * 删除指定ID学生操作
     */
    public void removeStudent() {
        // 获取指定删除的学生
        Integer id = findOne();

        // 是否确定删除
        if (id != -1 && service.confirm()) {
            client.sendMessage("deleteStu:" + id);
            System.out.println(client.receiveMessage());
        } else {
            System.out.println("删除操作撤销");
        }
    }

    /**
     * 修改指定ID学生信息
     */
    public void modifyStudent() {
        Integer id = service.getStringId();

        // 找到需要删除的学生
        client.sendMessage("findOne:" + id);
        String s = client.receiveMessage();

        // 如果说没有找到,返回是字符串是"查无此人"
        if (NOT_FOUND.equals(s)) {
            System.out.println(s);
            return;
        }

        String jsonString = service.modifyStudent(s);
        client.sendMessage("modifyStu:" + jsonString);
        String s1 = client.receiveMessage();
        System.out.println(s1);
    }

    /**
     * 展示一个学生信息
     *
     * @return 当前学生的ID号
     */
    public Integer findOne() {
        Integer id = service.getStringId();

        // 找到需要删除的学生
        client.sendMessage("findOne:" + id);
        String s = client.receiveMessage();

        // 如果说没有找到,返回是字符串是"查无此人"
        if (NOT_FOUND.equals(s)) {
            System.out.println(s);
            return -1;
        }

        service.showStudent(s);

        return id;
    }

    /**
     * 展示所有学生信息
     */
    public void findAll() {
        client.sendMessage("findAll:");

        String s = client.receiveMessage();
        if (EMPTY_SET.equals(s)) {
            System.out.println(s);
        } else {
            service.showStudentList(s);
        }
    }

    /**
     * 排序学生信息
     */
    public void sortStu() {
        Integer choose = service.sortChoose();

        if (11 == choose) {
            return;
        }

        client.sendMessage("sortStu:" + choose);
        String s = client.receiveMessage();

        if (EMPTY_SET.equals(s)) {
            System.out.println(s);
        } else {
            service.showStudentList(s);
        }
    }

    /**
     * 过滤学生信息
     */
    public void filterStu() {
        String s = service.ageFilter();

        client.sendMessage("filterStu:" + s);
        String s1 = client.receiveMessage();

        if (EMPTY_SET.equals(s)) {
            System.out.println(s);
        } else {
            service.showStudentList(s1);
        }
    }



}

3.2 客户端主程序(mainproject包中)

package com.qfedu.student.system.client.mainproject;

import com.qfedu.student.system.client.controller.ClientController;
import com.qfedu.student.system.client.util.ClientOperation;

import java.lang.reflect.InvocationTargetException;
import java.util.Scanner;

/**
 * 客户端主程序
 *
 * @author Anonymous 2020/3/18 11:17
 */
@SuppressWarnings("all")
public class ClientMain {

    private static Scanner sc = new Scanner(System.in);

    public static void main(String[] args)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        /* 核心控制层 */
        ClientController controller = new ClientController();
        /* 控制层Class对象 */
        Class<ClientController> cls = ClientController.class;

        /* 登陆 */
        controller.login();

        int choose = 0;

        while (true) {
            System.out.println("用户您好,骚磊学生系统");
            System.out.println("1. 查看所有学生");
            System.out.println("2. 查看指定学生");
            System.out.println("3. 增加学生信息");
            System.out.println("4. 修改指定学生");
            System.out.println("5. 删除指定学生");
            System.out.println("6. 指定信息排序");
            System.out.println("7. 指定信息筛选");
            System.out.println("8. 退出");

            choose = sc.nextInt();

            // 获取一个枚举类型数组
            ClientOperation[] values = ClientOperation.values();
            // 遍历枚举类型数组
            for (ClientOperation value : values) {
                // 找到对应枚举类型中的id和choose一致
                if (choose == value.getId()) {
                    // 使用反射指定对应的方法
                    cls.getMethod(value.getMethodName()).invoke(controller);
                    break;
                }
            }
        }

    }
}

3.3 客户端可以执行的操作(service包中)

package com.qfedu.student.system.client.service;

import com.qfedu.student.system.client.entity.Student;
import com.qfedu.student.system.client.util.JsonUtil;

import java.util.List;
import java.util.Scanner;

/**
 * 客户端可以执行的操作
 *
 * @author Anonymous 2020/3/17 15:55
 */
public class ClientService {

    private static Scanner sc = new Scanner(System.in);
    /**
     * 添加学生信息,到服务器
     *
     * @return Student数据对应的Json格式字符串
     */
    public String getStudent() {
        sc.next();
        System.out.println("请输入学生的姓名:");
        String name = sc.next();

        System.out.println("请输入学生的年龄:");
        Integer age = sc.nextInt();

        sc.next();

        System.out.println("请输入学生的性别 男 或者 女:");
        Boolean gender = sc.next().charAt(0) != '男';

        System.out.println("请输入学生的语文成绩:");
        Integer chnScore = sc.nextInt();

        System.out.println("请输入学生的数学成绩:");
        Integer mathScore = sc.nextInt();

        System.out.println("请输入学生的英语成绩:");
        Integer engScore = sc.nextInt();

        Integer totalScore = chnScore + mathScore + engScore;

        Student student = new Student(0, name, gender, age, mathScore, chnScore, engScore, totalScore, 0);

        return JsonUtil.studentToJson(student);
    }

    /**
     * 展示Json格式数据对应的保存Student数据List集合,
     * 可以用到展示所有学生,排序结果,过滤数据结果
     *
     * @param jsonString 包含所有学生数据的Json格式字符串
     */
    public void showStudentList(String jsonString) {
        List<Student> students = JsonUtil.jsonToStudentList(jsonString);

        for (Student student : students) {
            System.out.println(student);
        }
    }

    /**
     * 展示指定学生信息
     *
     * @param jsonString Json格式字符串
     */
    public void showStudent(String jsonString) {
        Student student = JsonUtil.jsonToStudent(jsonString);

        System.out.println(student);
    }

    /**
     * 修改指定学生信息
     *
     * @param jsonString 对应Json格式字符串
     * @return 修改之后的学生信息Json格式字符串
     */
    public String modifyStudent(String jsonString) {
        // 转换成对应的Student类型
        Student student = JsonUtil.jsonToStudent(jsonString);

        int choose = 0;
        boolean flag = false;

        while (true) {
            System.out.println("ID: " + student.getId() + " Name: " + student.getName());
            System.out.println("Age: " + student.getAge() + " Gender: " + (student.getGender() ? "女" : "男"));
            System.out.println("chnScore: " + student.getChnScore() + " mathScore: " + student.getMathScore());
            System.out.println("engScore: " + student.getEngScore() + " TotalScore: " + student.getTotalScore());
            System.out.println("Rank: " + student.getRank());

            System.out.println("1. 修改学生姓名:");
            System.out.println("2. 修改学生年龄:");
            System.out.println("3. 修改学生性别:");
            System.out.println("4. 修改学生语文成绩:");
            System.out.println("5. 修改学生数学成绩:");
            System.out.println("6. 修改学生英语成绩:");
            System.out.println("7. 退出");

            choose = sc.nextInt();
            sc.next();

            switch (choose) {
                case 1:
                    System.out.println("请输入学生的名字:");
                    String name = sc.next();

                    student.setName(name);
                    break;
                case 2:
                    System.out.println("请输入学生的年龄:");
                    Integer age = sc.nextInt();

                    student.setAge(age);
                    break;
                case 3:
                    System.out.println("请输入学生的性别 男 或者 女:");
                    Boolean gender = sc.next().charAt(0) != '男';

                    student.setGender(gender);
                    break;
                case 4:
                    System.out.println("请输入学生的语文成绩:");
                    Integer chnScore = sc.nextInt();

                    // 修改总分,获取原总分 + 当前语文成绩 - 原语文成绩
                    student.setTotalScore(student.getTotalScore() + chnScore - student.getChnScore());
                    student.setChnScore(chnScore);

                    break;
                case 5:
                    System.out.println("请输入学生的数学成绩:");
                    Integer mathScore = sc.nextInt();

                    student.setTotalScore(student.getTotalScore() + mathScore - student.getMathScore());
                    student.setMathScore(mathScore);
                    break;
                case 6:
                    System.out.println("请输入学生的英语成绩:");
                    Integer engScore = sc.nextInt();

                    student.setTotalScore(student.getTotalScore() + engScore - student.getEngScore());
                    student.setEngScore(engScore);
                    break;
                case 7:
                    flag = true;
                    break;
                default:
                    System.out.println("选择错误");
                    break;
            }

            // 退出标记
            if (flag) {
                // 退出while true循环
                break;
            }
        }

        // 讲修改之后的Student信息,转换成一个Json格式字符串返回
        return JsonUtil.studentToJson(student);
    }

    /**
     * 获取用户指定操作的ID号,可以用于查询,修改,删除操作
     *
     * @return 用户指定的学生id号
     */
    public Integer getStringId() {
        System.out.println("请输入学生的ID号:");

        return sc.nextInt();
    }

    /**
     * 是否继续操作的确定弹框
     *
     * @return 返回用户确定操作的消息
     */
    public boolean confirm() {
        System.out.println("确认当前操作吗? Y or N");
        return "Y".equalsIgnoreCase(sc.next());
    }

    /**
     * 用户排序选择操作
     *
     * @return 用户排序选择
     */
    public Integer sortChoose() {
        System.out.println("1. 年龄升序");
        System.out.println("2. 年龄降序");
        System.out.println("3. 数学成绩降序");
        System.out.println("4. 数学成绩升序");
        System.out.println("5. 语文成绩降序");
        System.out.println("6. 语文成绩升序");
        System.out.println("7. 英语成绩降序");
        System.out.println("8. 英语成绩升序");
        System.out.println("9. 总成绩降序");
        System.out.println("10. 总成绩升序");
        System.out.println("11. 排序取消");

        int choose = sc.nextInt();

        return Math.min(choose, 11);
    }

    /**
     * 用户返回过滤展示数据条件字符串
     *
     * @return 用户返回的过滤条件字符串
     */
    public String ageFilter() {
        System.out.println("请输入需要展示年龄的范围 最小值和最大值");
        int min = sc.nextInt();
        int max = sc.nextInt();

        // XXX, XXX
        if (min > max) {
            return max +"," + min;
        } else {
            return min +"," + max;
        }
    }

    /**
     * 返回用户登陆的有效信息
     *
     * @return 用户登陆信息
     */
    public String loginMessage() {
        System.out.println("欢迎来到骚磊学生系统:");
        System.out.println("请输入用户名:");
        String userName = sc.next();

        System.out.println("请输入密码:");
        String password = sc.next();

        return userName + ":" + password;
    }
}

3.4 使用NIO完成客户端服务器连接,数据接收,数据发送过程(tcp包中)

package com.qfedu.student.system.client.tcp;

import com.qfedu.student.system.client.util.CloseUtil;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

/**
 * 使用NIO完成客户端服务器连接,数据接收,数据发送过程
 *
 * @author Anonymous 2020/3/18 09:41
 */
public class ClientTcp {
    /**
     * NIO Socket客户端
     */
    private SocketChannel socket = null;

    /**
     * 服务器IP地址
     */
    private static String host = "192.168.31.154";

    /**
     * 服务器对应当前服务器的端口号
     */
    private static int port = 8848;

    /**
     * ClientTcp构造方法,这里需要连接服务器得到TCP协议的客户端SocketChannel对象
     */
    public ClientTcp() {
        try {
            // 1. 开启SocketChannel NIO服务器
            socket = SocketChannel.open();

            // 2. 设置当前NIO方式为非阻塞方式
            socket.configureBlocking(false);

            // 3. 确定连接主机IP地址和端口号学习的InetSocketAddress
            InetSocketAddress address = new InetSocketAddress(host, port);

            // 4. 连接服务器
            if (!socket.connect(address)) {
                while (!socket.finishConnect()) {
                    Thread.sleep(2000);
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从服务器接收数据
     *
     * @return 从服务器接收到的数据
     */
    public String receiveMessage() {

        int length = -1;
        String str = null;

        // 存在可能性 1024不够用!!!
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        try {
            StringBuilder stb = new StringBuilder();

            while ((length = socket.read(buffer)) == 0) {}

            stb.append(new String(buffer.array(), 0, length));

            while ((length = socket.read(buffer)) > 0) {
                stb.append(new String(buffer.array(), 0, length));
            }

            str = stb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return str;
    }

    /**
     * 发送数据给服务器,如果发送的数据是 "close:" 标记
     *
     * @param message 需要发送的数据
     */
    public void sendMessage(String message) {
        ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());

        try {
            socket.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if ("close:".equals(message)) {
                // 关闭客户端Socket
                CloseUtil.closeAll(socket);
            }
        }
    }
}

四,包名布局截图

4.1 服务端截图

在这里插入图片描述

客户端截图

在这里插入图片描述

发布了41 篇原创文章 · 获赞 0 · 访问量 1730

猜你喜欢

转载自blog.csdn.net/qq_39544980/article/details/104957028