Versión simple de la consola de administración Express: agrega programación de red y subprocesos múltiples (versión completa, código fuente completo adjunto) (Java)


Para conocer la versión de almacenamiento de matriz, consulte el artículo: Versión simple de Express Management Console - Versión de almacenamiento de matriz (Java)

Para conocer la versión de almacenamiento de la colección de listas, consulte el artículo: Versión simple de Express Management Console - Versión de almacenamiento de la colección de listas (Java)

Para conocer la versión de almacenamiento de la colección de mapas, consulte el artículo: Versión simple de Express Management Console - Versión de almacenamiento de la colección de mapas (Java)

El uso de la tecnología IO para implementar el almacenamiento de datos basado en la versión de almacenamiento de la colección de mapas puede consultar el artículo: Versión simple de Express Management Console: uso de IO Streams (Java)

  • La versión de almacenamiento de matriz utilizaMatriz bidimensionalPara almacenar entrega urgente, la posición de entrega urgente corresponde a los dos subíndices de la matriz bidimensional.

  • Se adopta la versión de almacenamiento de la colección de listascolección de listasEntrega urgente en tienda

  • Se adopta la versión de almacenamiento de la colección de mapas.colección de mapasLa ventaja de utilizar una colección de mapas para almacenar entrega urgente es que Map es un par clave-valor , la clave es el número de entrega urgente y el valor es el objeto de entrega urgente, lo que garantiza que el número de entrega urgente sea único.

  • El uso de flujos IO se optimiza en función de la versión de almacenamiento de la colección de mapas. La tecnología IO se utiliza para almacenar datos exprés en archivos y leer datos de archivos. Después de que el archivo almacena información exprés, se puede leer desde el archivo cada vez que se ejecuta la aplicación. iniciado

  • Con respecto a la programación de red y subprocesos múltiples , se agrega tecnología de programación de red y subprocesos múltiples para realizar la interacción de datos entre el cliente y el servidor, y se utiliza subprocesos múltiples para que después de que cada usuario envíe una solicitud de inicio de sesión al servidor, el servidor asigne un hilo para procesar la solicitud.


requerimiento específico

  1. Implemente la función de inicio de sesión de usuario según el modo de programación de red y comprenda los conceptos de cliente y servidor. El cliente se utiliza para obtener información del usuario y el servidor se utiliza para el almacenamiento de datos y el juicio lógico.
  2. Sobre la base de la programación de la red, el modo de subprocesos múltiples se habilita en el lado del servidor y cada usuario debe enviar una solicitud de inicio de sesión al servidor. El lado del servidor asigna un subproceso para procesar la solicitud para realizar el inicio de sesión del usuario en el lado del servidor. -modo de enhebrado.

Involucrando puntos de conocimiento.

  1. orientado a objetos
  2. recolectar
  3. OI
  4. subprocesos múltiples
  5. programación de red

Ideas e implementación de código.

1. Excepciones personalizadas

Cree un paquete de excepción y cree una nueva clase OutNumberBoundException

OutNumberBoundExcepción

public class OutNumberBoundException extends Throwable {
    
    
    public OutNumberBoundException(String s) {
    
    
        super(s);
    }
}

2. Kit de herramientas

Cree un paquete de utilidades y cree una nueva clase IOUtil

IUtil

Clase de herramienta de lectura y escritura de archivos, por lo que se recomiendan métodos estáticos

  • Leer datos del archivo especificado
public static Object readFile(String fileName) throws IOException, ClassNotFoundException {
    
    
        FileInputStream fis = new FileInputStream(fileName);//指定文件
        ObjectInputStream ois = new ObjectInputStream(fis);
        return ois.readObject();//读出数据
    }
  • Escribir datos en el archivo especificado.
 public static void writeFile(Object obj,String fileName) throws IOException {
    
    
        FileOutputStream fos = new FileOutputStream(fileName);//指定文件
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(obj);//写入数据obj
    }

3. Objeto

Crea un paquete pojo y crea una nueva clase Express

Expresar

  • Defina propiedades y establezca y obtenga valores con definidores y captadores
	private String number;//快递单号
    private String company;//公司
    private int code;//取件码
    private int x;
    private int y;
    
	 /**
     * 使用setter和getter设置和获取值
     */
    public String getNumber() {
    
    
        return number;
    }

    public void setNumber(String number) {
    
    
        this.number = number;
    }

    public String getCompany() {
    
    
        return company;
    }

    public void setCompany(String company) {
    
    
        this.company = company;
    }

    public int getCode() {
    
    
        return code;
    }

    public void setCode(int code) {
    
    
        this.code = code;
    }

    public int getX() {
    
    
        return x;
    }

    public void setX(int x) {
    
    
        this.x = x;
    }

    public int getY() {
    
    
        return y;
    }

    public void setY(int y) {
    
    
        this.y = y;
    }
  • Definir constructores sin parámetros y con parámetros completos.
/**
     * 定义无参构造方法
     */
    public Express() {
    
    
    }

    /**
     * 定义全参构造方法
     */
    public Express(String number, String company, int code, int x, int y) {
    
    
        this.number = number;
        this.company = company;
        this.code = code;
        this.x = x;
        this.y = y;
    }
  • Anula toString para convertir información en una cadena
    /**
     * toString将信息转化为字符串形式
     */
    @Override
    public String toString() {
    
    
        return "快递信息[" +
                "快递单号:" + getNumber() + ' ' +
                ", 快递公司:" + getCompany() + ' ' +
                ", 取件码:" + getCode() + " , 在第" + (getX() + 1) + "行 第" + (getY() + 1) + "列柜子" +
                ']';
    }

4. Procesamiento de datos

Cree un paquete dao y cree una nueva clase Dao

dao

  • Crear archivos e inicializar datos
    public static final String FILE_NAME = "快递信息.txt";
    
    //静态 代码块
    static {
    
    
        File file = new File(FILE_NAME);
        if (!file.exists()){
    
    //如果文件不存在,创建文件
            try {
    
    
                if (file.createNewFile()){
    
    //创建文件名为FILE_NAME的文件
                    System.out.println("第一次启动项目,创建储存文件成功!");
                }
            } catch (IOException e) {
    
    
                System.out.println(e.getMessage());
            }
        }
    }
    
    //初始化数据
    public Dao() {
    
    
        //从文件中读取数据
        try {
    
    
            Object obj = IOUtil.readFile(FILE_NAME);
            if (obj!=null && obj instanceof List){
    
    
                expressList = (List<Express>) obj;
            }
        }catch (IOException | ClassNotFoundException e) {
    
    
            System.out.println(e.getMessage());
        }
    }
  • Añadir mensajero
    public static Express add(Express express) throws Exception {
    
    
        Random random = new Random();
        if (expressList.size() == 100) {
    
    
            System.out.println("快递柜已存满!");
            return null;
        }
        int x, y;
        do {
    
    
            x = random.nextInt(10);
            y = random.nextInt(10);
        } while (isExist(x, y));

        int code;
        do {
    
    
            code = random.nextInt(900000) + 100000;
        } while (isExistCode(code));
        express.setCode(code);
        express.setX(x);
        express.setY(y);
        expressList.add(express);
        IOUtil.writeFile(expressList,FILE_NAME);//更新文档中的数据
        return express;
    }

  • Determinar si ya existe un mensajero en la ubicación actual
    public static boolean isExist(int x, int y) {
    
    
        for (Express express : expressList) {
    
    
            if (express.getX() == x && express.getY() == y) {
    
    
                return true;
            }
        }
        return false;
    }
  • Determinar si existe el código de recogida generado aleatoriamente
    public static boolean isExistCode(int code) {
    
    
        for (Express express : expressList) {
    
    
            if (express.getCode() == code) {
    
    
                return true;
            }
        }
        return false;
    }
  • Eliminar expreso
    public static boolean delete(String number) throws Exception {
    
    
        int index = findByNumber(number);
        if (index == -1) {
    
    
            return false;
        }
        expressList.remove(index);//删除快递的操作
        IOUtil.writeFile(expressList,FILE_NAME);
        return true;
    }
  • Consultar entrega urgente según el número de entrega urgente
    public static int findByNumber(String number) {
    
    
        int i = 0;
        for (Express express : expressList) {
    
    
            if (number.equals(express.getNumber())) {
    
    
                return i;
            }
            i++;
        }
        return -1;
    }
  • Actualización rápida
    public static boolean update(String number, Express newExpress) throws Exception {
    
    
        int index = findByNumber(number);
        if (index == -1) {
    
    
            System.out.println("快递不存在!");
            return false;
        }
        Express express1 = expressList.get(index);
        express1.setNumber(newExpress.getNumber());
        express1.setCompany(newExpress.getCompany());
        IOUtil.writeFile(expressList,FILE_NAME);//数据加入
        return true;
    }
  • Obtenga toda la información del mensajero
    public static List<Express> getExpressList() {
    
    
        return expressList;
    }
  • recoger mensajero
    public Express findByCodeAndDelete(int code) throws Exception {
    
    
        Express express = findExpressByCode(code);
        if (express!=null){
    
    
            if (delete(express.getNumber())){
    
    
                return express;
            }
        }
        return null;
    }
  • Encuentra un mensajero por código de recogida
    public static Express findExpressByCode(int code){
    
    
        for (int i = 0;i<expressList.size();i++) {
    
    
            if (expressList.get(i).getCode() == code){
    
    
                return expressList.get(i);
            }
        }
        return null;
    }

5. Programación de red C/S

  • Principalmente responsable de la interacción entre el servidor y el cliente.

Cree un paquete de socket y cree nuevas clases Servidor y Cliente

servidorservidor

Cree el objeto Servidor en main y llame al método de inicio

    public static void main(String[] args) {
    
    
        Server server = new Server();
        server.start();
    }

A continuación, escriba el método de inicio para iniciar el servidor:


Primero crea el servidor.

	//端口号
    private final int PORT = 10086; 
    
    //创建一个服务器
    private ServerSocket server; 

1. Cree el método de inicio para configurar y ejecutar el servidor y conectar el cliente.

  • Después de ingresar al servidor, espere a que el cliente se conecte y
    use un bucle while para realizar múltiples conexiones del usuario.
	server = new ServerSocket(PORT);//端口号传入到服务器
	System.out.println("服务器已经准备好!服务端口:" + PORT);
	//等待客户端得连接
	while (true) {
    
    //实现多用户连接,使用用while循环
		Socket client = server.accept();//连接服务器得客户端
        System.out.println("客户端" + client.hashCode() + "连接成功");//不同的hashcode表示不同的对象
    }
  • Únase a subprocesos múltiples y utilice clases internas anónimas
	//为每个客户单独开一个线程处理请求
	new Thread(new Runnable() {
    
    
		@Override
		public void run() {
    
    
        //客户端得请求   接受客户端得请求  读数据 -- 处理完毕之后将结果相应给客户端 ---写数据到客户端
        	try {
    
    
            	init(client);//用户的方法  方法里包括了序列化和反序列化
            } catch (IOException|Exception e) {
    
    
            	e.printStackTrace();
            } 
        }
     }).start();

El código completo del método start() es el siguiente:

    //开启一个线程 服务端开启的方法
    public void start() {
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    server = new ServerSocket(PORT);//端口号传入到服务器
                    System.out.println("服务器已经准备好!服务端口:" + PORT);
                    //等待客户端得连接
                    while (true) {
    
    //实现多用户连接,使用用while循环
                        Socket client = server.accept();//连接服务器得客户端
                        System.out.println("客户端" + client.hashCode() + "连接成功");//不同的hashcode表示不同的对象
                        //为每个客户单独开一个线程处理请求
                        new Thread(new Runnable() {
    
    
                            @Override
                            public void run() {
    
    
                                //客户端得请求   接受客户端得请求  读数据 -- 处理完毕之后将结果相应给客户端 ---写数据到客户端
                                try {
    
    
                                    init(client);//用户的方法  方法里包括了序列化和反序列化
                                } catch (IOException|Exception  e) {
    
    
                                    e.printStackTrace();
                                }
                            }
                        }).start();
                    }
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();
    }

2. Escriba el método init en la ejecución de la tarea para implementar la interacción con los datos del cliente.

  • recibir mensajes
        InputStream is = null;
        ObjectInputStream in = null;
  • enviar mensaje
        OutputStream os = null;
        ObjectOutputStream out = null;
  • Obtener objeto de flujo
		is = client.getInputStream();
    	os = client.getOutputStream();
   		out = new ObjectOutputStream(os);
    	in = new ObjectInputStream(is);
  • entrar al sistema
       System.out.println("用户得请求类型" + flag + "线程" + Thread.currentThread().getName() + "为你服务!");
  • Obtener las operaciones específicas del usuario.
		String flag = in.readUTF();
		System.out.println(flag);
    • Añadir mensajero
                    //获取客户端发布的参数
                    Express express = (Express) in.readObject();
                    express = dao.add(express);
                    out.writeObject(express);
    • Eliminar expreso
                    String number = in.readUTF();
                    boolean res = dao.delete(number);
                    out.writeObject(res);
    • Modificar entrega urgente
                    String number =in.readUTF();//旧数据
                    Express newExpress = (Express) in.readObject();
                    boolean res = dao.update(number, newExpress);
    • Imprimir todos los envíos
                	//在服务器端打印当前快递存储信息
                    System.out.println("-----------------------------------执行findadll");
                    List<Express> expressList = dao.getExpressList();
                    //获取处理结果 返回给客户端写数据
                    if (expressList != null && expressList.size() != 0) {
    
    
                        System.out.println("----------------当前快递信息如下,准备发给客户端---------------------------");
                        for (Express express : expressList) {
    
    //遍历
                            System.out.println("--" + express);
                        }
                        out.reset();
                        out.writeObject(expressList);
                        System.out.println("发送成功!");
                    } else
                        out.writeObject("快递柜中暂时没有任何快递");
                        out.flush();
    • Levantar
                    Integer code = in.readInt();
                    Express res = dao.findByCodeAndDelete(code);
                    System.out.println("res:"+res);
                    out.writeObject(res);
  • cerrar flujo
		if (in != null) {
    
    
			in.close();
			}
        if (out != null) {
    
    
            out.close();
        }

El código completo del método init es el siguiente:

	//接受客户端得请求  读数据 -- 处理完毕之后将结果相应给客户端 ---写数据到客户端
    public void init(Socket client) throws Exception {
    
    
        OutputStream os = null;
        ObjectOutputStream out = null;
        InputStream is = null;
        ObjectInputStream in = null;

        //获取流对象
        try {
    
    
            is = client.getInputStream();
            os = client.getOutputStream();
            out = new ObjectOutputStream(os);
            in = new ObjectInputStream(is);
            //获取客户端得发送得请求类型
            while (true) {
    
    
                System.out.println("用户得请求类型" + flag + "线程" + Thread.currentThread().getName() + "为你服务!");
                
                String flag = in.readUTF();
                System.out.println(flag);
                if ("printAll".equals(flag)) {
    
    
                	//在服务器端打印当前快递存储信息
                    System.out.println("-----------------------------------执行findadll");
                    List<Express> expressList = dao.getExpressList();
                    //获取处理结果 返回给客户端写数据
                    if (expressList != null && expressList.size() != 0) {
    
    
                        System.out.println("----------------当前快递信息如下,准备发给客户端---------------------------");
                        for (Express express : expressList) {
    
    //遍历
                            System.out.println("--" + express);
                        }
                        out.reset();
                        out.writeObject(expressList);
                        System.out.println("发送成功!");
                    } else
                        out.writeObject("快递柜中暂时没有任何快递");
                        out.flush();
                    continue;
                } else if ("insert".equals(flag)) {
    
    
                    //获取客户端发布的参数
                    Express express = (Express) in.readObject();
                    express = dao.add(express);
                    out.writeObject(express);
                    continue;
                } else if ("update".equals(flag)) {
    
    
                    String number =in.readUTF();//旧数据
                    Express newExpress = (Express) in.readObject();
                    boolean res = dao.update(number, newExpress);
                    out.writeObject(res);
                    continue;
                } else if ("delete".equals(flag)) {
    
    
                    String number = in.readUTF();
                    boolean res = dao.delete(number);
                    out.writeObject(res);
                    continue;
                } else if ("findByCode".equals(flag)) {
    
    //取件 先查询后删除
                    Integer code = in.readInt();
                    Express res = dao.findByCodeAndDelete(code);
                    System.out.println("res:"+res);
                    out.writeObject(res);
                    continue;
                } else {
    
    
                    out.writeObject("你的请求服务器暂时处理不了");
                    continue;
                }
            }//end while
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (in != null) {
    
    
                in.close();
            }
            if (out != null) {
    
    
                out.close();
            }
        }
    }//end void

cliente cliente

Cree un objeto Cliente en main y llame al método de inicio para permitir que los usuarios se conecten al servidor.

    public static void main(String[] args) {
    
    
        Client c = new Client();
        c.start();
    }

Primero crea el cliente.

    private final int PORT = 10086;//客户端要链接的端口号
    
    private Socket client;//客户端

1. Cree el método de inicio , ejecute el cliente y conéctese al servidor.

  • recibir mensajes
        InputStream is = null;
        ObjectInputStream in = null;
  • enviar mensaje
        OutputStream os = null;
        ObjectOutputStream out = null;
  • conectarse al servidor
            do {
    
    
                if (client == null || client.isClosed()) {
    
    
                    client = new Socket("127.8.0.1", PORT);
                    in = client.getInputStream();
                    out = client.getOutputStream();
                    objectOutputStream = new ObjectOutputStream(out);
                    objectInputStream = new ObjectInputStream(in);
                    System.out.println("客户端连接服务器成功!");
                }
            } while (mainMenu(objectInputStream, objectOutputStream) != 0);
  • Salga del sistema y cierre la transmisión.
		if (objectInputStream != null) {
    
    
			objectInputStream.close();
		}
	    if (objectOutputStream != null) {
    
    
			objectOutputStream.close();
	    }
		if (client != null) {
    
    
			client.close();
		}

El método completo de inicio es el siguiente:

    //客户端启动的方法
    public void start() {
    
    
        OutputStream out = null;
        ObjectOutputStream objectOutputStream = null;
        InputStream in = null;
        ObjectInputStream objectInputStream = null;
        //获取流对象
        try {
    
    
            do {
    
    
                if (client == null || client.isClosed()) {
    
    
                    client = new Socket("127.8.0.1", PORT);
                    in = client.getInputStream();
                    out = client.getOutputStream();
                    objectOutputStream = new ObjectOutputStream(out);
                    objectInputStream = new ObjectInputStream(in);
                    System.out.println("客户端连接服务器成功!");
                }
            } while (mainMenu(objectInputStream, objectOutputStream) != 0);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } catch (OutNumberBoundException e) {
    
    
            e.printStackTrace();
        } finally {
    
    //关闭流
            try {
    
    
                if (objectInputStream != null) {
    
    
                    objectInputStream.close();
                }
                if (objectOutputStream != null) {
    
    
                    objectOutputStream.close();
                }
                if (client != null) {
    
    
                    client.close();
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }//end finally
    }//end void start

2. Menú principal

    public static int mainMenu(ObjectInputStream in, ObjectOutputStream out) throws OutNumberBoundException, Exception {
    
    
        int mainNum = 0;
        do{
    
    
            System.out.println("----------欢迎使用快递管理系统----------");
            System.out.println("请选择您的身份:");
            System.out.println("1.管理员");
            System.out.println("2.普通用户");
            System.out.println("0.退出");
            String s = input.nextLine();
            try{
    
    
                mainNum = validNum(s,0,2);
                break;
            }catch(NumberFormatException | OutNumberBoundException e){
    
    
                System.out.println(e.getMessage());
            }
        }while(true);
        switch(mainNum){
    
    
            case 0://结束使用
                System.out.println("感谢使用快递管理系统!");
                break ;
            case 1://进入管理员平台
                managerPlatform(in,out);
                break ;
            case 2://进入用户平台
                userPlatform(in,out);
                break ;
        }
        return mainNum;
    }//end mainMenu()
  • Determinar si la entrada es un número válido
    private static int validNum(String s,int begin,int end) throws NumberFormatException, OutNumberBoundException {
    
    
        try{
    
    
            int num = Integer.parseInt(s);
            if (num < begin || num > end){
    
    
                throw new OutNumberBoundException("数字的范围必须在" + begin + "和" + end +"之间");
            }
            return num;
        }catch(NumberFormatException | OutNumberBoundException e){
    
    
            throw new NumberFormatException("输入的必须是数字!");
        }
    }

2.1 Interfaz de administrador

    public static void managerPlatform(ObjectInputStream in, ObjectOutputStream out) throws OutNumberBoundException, Exception{
    
    
        w:while(true){
    
    
            int managerNum = 0;
            do{
    
    
                System.out.println("尊敬的管理员,您好!");
                System.out.println("请选择您要进行的操作:");
                System.out.println("1.录入快递");
                System.out.println("2.删除快递");
                System.out.println("3.修改快递");
                System.out.println("4.查看所有快递");
                System.out.println("0.返回上一级界面");
                String s = input.nextLine();
                try{
    
    
                    managerNum = validNum(s,0,4);
                    break;
                }catch(NumberFormatException | OutNumberBoundException e){
    
    
                    System.out.println(e.getMessage());
                }
            }while(true);
            switch(managerNum){
    
    
                case 0:{
    
    //返回上一级页面
                    return;
                }
                case 1:{
    
    //1.录入快递
                    insert(in,out);
                }
                break w;
                case 2:{
    
    //2.删除快递
                    delete(in,out);
                }
                break w;
                case 3:{
    
    //3.修改快递
                    update(in,out);
                }
                break w;
                case 4:{
    
    //4.查看所有快递
                    printAll(in,out);
                }
                break w;
            }// end switch
        }//end while
    }//end managerPlatform

  • Añadir mensajero
    private static void insert(ObjectInputStream in, ObjectOutputStream out) {
    
    
        System.out.println("---------存快递----------");
        Express express = new Express();
        System.out.print("请输入快递单号:");
        express.setNumber(input.nextLine());
        System.out.print("请输入快递公司:");
        express.setCompany(input.nextLine());
        //当前快递单号不存在,存快递
        if(Server.dao.findByNumber(express.getNumber()) == -1){
    
    
            try {
    
    
                out.writeUTF("insert");
                out.writeObject(express);
                out.flush();
                //接受服务器端的响应---读数据
                Object object = in.readObject();
                if (object instanceof Express) {
    
    
                    express = (Express) object;
                    System.out.println("添加成功!快递在第" + (express.getX() + 1) + "排,第" + (express.getY() + 1) + "列");
                } else {
    
    
                    System.out.println("添加失败" + object);
                }
            } catch (Exception exception) {
    
    
                System.out.println("系统异常,添加失败!");
                System.out.println(exception.getMessage());
            }
        }else{
    
    
            System.out.println("该快递单号已存在!快递添加失败!");
        }
    }
  • Eliminar expreso
    private static void delete(ObjectInputStream in, ObjectOutputStream out) {
    
    
        System.out.println("删除快递");
        System.out.print("请输入要删除的快递单号:");
        String number = input.nextLine();
        int exist = Server.dao.findByNumber(number);
        if (exist == -1) {
    
    
            System.out.println("快递不存在!");
        } else {
    
    
            int deleteNum;
            do {
    
    
                System.out.println("是否进行删除操作?");
                System.out.println("1.确认删除");
                System.out.println("0.取消操作");
                String s = input.nextLine();
                deleteNum = -1;
                try {
    
    
                    deleteNum = validNum(s, 0, 1);
                    break;
                } catch (NumberFormatException | OutNumberBoundException e) {
    
    
                    System.out.println(e.getMessage());
                }
            } while (true);
            if (deleteNum == 0) {
    
    
                System.out.println("取消删除成功!");
            } else {
    
    
                try {
    
    
                    out.writeUTF("delete");
                    out.writeUTF(number);
                    out.flush();
                    Object obj = in.readObject();
                    if (obj instanceof Boolean) {
    
    
                        boolean res = (boolean) obj;
                        if (res == true) {
    
    
                            System.out.println("删除成功");
                        } else {
    
    
                            System.out.println("删除失败");
                        }
                    } else {
    
    
                        System.out.println("删除失败!!!!!!");
                    }
                } catch (Exception e) {
    
    
                    System.out.println("系统异常,删除失败!");
                    System.out.println(e.getMessage());
                }
            }// end else  option of delete
        }//end else express exist
    }//end method
  • Modificar entrega urgente
    private static void update(ObjectInputStream in, ObjectOutputStream out) {
    
    
        System.out.println("---------修改快递-----------");
        System.out.print("请输入要修改的快递单号:");
        String number = input.nextLine();
        int exist = Server.dao.findByNumber(number);
        if(exist == -1){
    
    
            System.out.println("快递不存在!");
        }else{
    
    
            Express newExpress = new Express();
            System.out.print("请输入新的快递单号:");
            newExpress.setNumber(input.nextLine());
            System.out.print("请输入新的公司名称:");
            newExpress.setCompany(input.nextLine());
            try {
    
    
                out.writeUTF("update");
                out.flush();
                out.writeUTF(number);
                out.flush();
                out.writeObject(newExpress);
                out.flush();
                Object obj = in.readObject();
                if (obj instanceof Boolean) {
    
    
                    boolean res = (boolean) obj;
                    if (res == true) {
    
    
                        System.out.println("更新成功!");
                    } else {
    
    
                        System.out.println("更新失败!");
                    }
                } else{
    
    
                    System.out.println("更新失败!!!!!!");
                }
            } catch (Exception e) {
    
    
                System.out.println("系统异常,更新失败!");
                System.out.println(e.getMessage());
            }
        }// end else(option of exist then update)
    }//end update method
  • Imprimir todos los envíos
    public static void printAll(ObjectInputStream in, ObjectOutputStream out) throws IOException, ClassNotFoundException {
    
    
        System.out.println("--------当前快递存储情况---------");
        out.writeUTF("printAll");//与Server相对应,发送给服务器请求类型
        out.flush();
        Object obj = in.readObject();
        if (obj instanceof List) {
    
    
            List<Express> expressList = (List<Express>) obj;//强转
            for (Express express : expressList) {
    
    //遍历输出
                System.out.println(express);
            }
        }else {
    
    
            System.out.println(obj);
        }
    }

2.2 Interfaz de usuario

  • Levantar
    public static void userPlatform(ObjectInputStream in, ObjectOutputStream out) throws OutNumberBoundException, Exception {
    
    
        int code = -1;
        do {
    
    
            System.out.print("请输入取件码:");
            String s = input.nextLine();
            try {
    
    
                code = validNum(s, 100000, 999999);
                break;
            } catch (NumberFormatException | OutNumberBoundException e) {
    
    
                System.out.println(e.getMessage());
            }
        } while (true);
        out.writeUTF("findByCode");
        out.writeInt(code);
        out.flush();
        Object obj = in.readObject();
        if (obj instanceof Express) {
    
    
            Express e = (Express) obj;
            System.out.println("快递信息:" + e);
            System.out.println("您的快递存储在快递柜的第" + (e.getX() + 1) + "排,第" + (e.getY() + 1) + "列,取件愉快~");

        } else {
    
    
            System.out.println("快递不存在,取件失败!");
        }
    }

código completo

1. Excepciones personalizadas

OutNumberBoundExcepción

public class OutNumberBoundException extends Throwable {
    
    
    public OutNumberBoundException(String s) {
    
    
        super(s);
    }
}

2. Kit de herramientas

IUtil

/**
 * 文件读写技术
 *
 */
public class IOUtil {
    
    
    /**
     * 从指定的文件中读取数据
     * Reader
     * InputStream
     */
    public static Object readFile(String fileName) throws IOException, ClassNotFoundException {
    
    
        FileInputStream fis = new FileInputStream(fileName);//指定文件
        ObjectInputStream ois = new ObjectInputStream(fis);
        return ois.readObject();//读出数据
    }

    /**
     * 写入数据到指定文件
     * Writer
     * OutputStream
     */
    public static void writeFile(Object obj,String fileName) throws IOException {
    
    
        FileOutputStream fos = new FileOutputStream(fileName);//指定文件
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(obj);//写入数据obj
    }

}

3. Objeto

Expresar

public class Express implements Serializable {
    
    
    private String number;//快递单号
    private String company;//公司
    private int code;//取件码
    private int x;
    private int y;

    /**
     * 定义无参构造方法
     */
    public Express() {
    
    
    }

    /**
     * 定义全参构造方法
     */
    public Express(String number, String company, int code, int x, int y) {
    
    
        this.number = number;
        this.company = company;
        this.code = code;
        this.x = x;
        this.y = y;
    }

    /**
     * 使用setter和getter设置和获取值
     */
    public String getNumber() {
    
    
        return number;
    }

    public void setNumber(String number) {
    
    
        this.number = number;
    }

    public String getCompany() {
    
    
        return company;
    }

    public void setCompany(String company) {
    
    
        this.company = company;
    }

    public int getCode() {
    
    
        return code;
    }

    public void setCode(int code) {
    
    
        this.code = code;
    }

    public int getX() {
    
    
        return x;
    }

    public void setX(int x) {
    
    
        this.x = x;
    }

    public int getY() {
    
    
        return y;
    }

    public void setY(int y) {
    
    
        this.y = y;
    }

    /**
     * toString将信息转化为字符串形式
     */
    @Override
    public String toString() {
    
    
        return "快递信息[" +
                "快递单号:" + getNumber() + ' ' +
                ", 快递公司:" + getCompany() + ' ' +
                ", 取件码:" + getCode() + " , 在第" + (getX() + 1) + "行 第" + (getY() + 1) + "列柜子" +
                ']';
    }
}

4. Procesamiento de datos

dao

public class Dao {
    
    
    //链表的初始设置
    private static List<Express> expressList = new ArrayList<>(100);
    //存储快递的文件名
    public static final String FILE_NAME = "快递信息.txt";

    //静态 代码块
    static {
    
    
        File file = new File(FILE_NAME);
        if (!file.exists()){
    
    //如果文件不存在,创建文件
            try {
    
    
                if (file.createNewFile()){
    
    //创建文件名为FILE_NAME的文件
                    System.out.println("第一次启动项目,创建储存文件成功!");
                }
            } catch (IOException e) {
    
    
                System.out.println(e.getMessage());
            }
        }
    }
    
    //初始化数据
    public Dao() {
    
    
        //从文件中读取数据
        try {
    
    
            Object obj = IOUtil.readFile(FILE_NAME);
            if (obj!=null && obj instanceof List){
    
    
                expressList = (List<Express>) obj;
            }
        }catch (IOException | ClassNotFoundException e) {
    
    
            System.out.println(e.getMessage());
        }
    }


    /**
     * 获得快递的所有信息
     * @return
     */
    public static List<Express> getExpressList() {
    
    
        return expressList;
    }


    /**
     * 添加快递
     * @param express
     * @return
     * @throws Exception
     */
    public static Express add(Express express) throws Exception {
    
    
        Random random = new Random();
        if (expressList.size() == 100) {
    
    
            System.out.println("快递柜已存满!");
            return null;
        }
        int x, y;
        do {
    
    
            x = random.nextInt(10);
            y = random.nextInt(10);
        } while (isExist(x, y));

        int code;
        do {
    
    
            code = random.nextInt(900000) + 100000;
        } while (isExistCode(code));
        express.setCode(code);
        express.setX(x);
        express.setY(y);
        expressList.add(express);
        IOUtil.writeFile(expressList,FILE_NAME);//更新文档中的数据
        return express;
    }


    /**
     * 添加快递中,判断当前位置是否已经存在快递
     * @param x
     * @param y
     * @return
     */
    public static boolean isExist(int x, int y) {
    
    
        for (Express express : expressList) {
    
    
            if (express.getX() == x && express.getY() == y) {
    
    
                return true;
            }
        }
        return false;
    }

    /**
     * 判断取件码是否已经存在
     * @param code
     * @return
     */
    public static boolean isExistCode(int code) {
    
    
        for (Express express : expressList) {
    
    
            if (express.getCode() == code) {
    
    
                return true;
            }
        }
        return false;
    }

    /**
     * 根据快递单号查找快递,如果不存在返回-1
     * @param number
     * @return
     */
    public static int findByNumber(String number) {
    
    
        int i = 0;
        for (Express express : expressList) {
    
    
            if (number.equals(express.getNumber())) {
    
    
                return i;
            }
            i++;
        }
        return -1;
    }


    /**
     * 删除快递
     * @param number
     * @return
     * @throws Exception
     */
    public static boolean delete(String number) throws Exception {
    
    
        int index = findByNumber(number);
        if (index == -1) {
    
    
            return false;
        }
        expressList.remove(index);//删除快递的操作
        IOUtil.writeFile(expressList,FILE_NAME);
        return true;
    }


    /**
     * 更新快递
     * @param number
     * @param newExpress
     * @return
     * @throws Exception
     */
    public static boolean update(String number, Express newExpress) throws Exception {
    
    
        int index = findByNumber(number);
        if (index == -1) {
    
    
            System.out.println("快递不存在!");
            return false;
        }
        Express express1 = expressList.get(index);
        express1.setNumber(newExpress.getNumber());
        express1.setCompany(newExpress.getCompany());
        IOUtil.writeFile(expressList,FILE_NAME);//数据加入
        return true;
    }

    /**
     * 通过取件码查找快递
     * @param code
     * @return
     */
    public static Express findExpressByCode(int code){
    
    
        for (int i = 0;i<expressList.size();i++) {
    
    
            if (expressList.get(i).getCode() == code){
    
    
                return expressList.get(i);
            }
        }
        return null;
    }

    /**
     * 取件,删除快递
     * @param code
     * @return
     * @throws IOException
     */
    public Express findByCodeAndDelete(int code) throws Exception {
    
    
        Express express = findExpressByCode(code);
        if (express!=null){
    
    
            if (delete(express.getNumber())){
    
    
                return express;
            }
        }
        return null;
    }
}

5. Programación de red C/S

Servidor

public class Server {
    
    
    public static Dao dao = new Dao();
    public static void main(String[] args) {
    
    
        Server server = new Server();
        server.start();
    }

    private final int PORT = 10086; //端口号

    private ServerSocket server; //建立一个服务器

    //开启一个线程 服务端开启的方法
    public void start() {
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    server = new ServerSocket(PORT);//端口号传入到服务器
                    System.out.println("服务器已经准备好!服务端口:" + PORT);
                    //等待客户端得连接
                    while (true) {
    
    //实现多用户连接,使用用while循环
                        Socket client = server.accept();//连接服务器得客户端
                        System.out.println("客户端" + client.hashCode() + "连接成功");//不同的hashcode表示不同的对象
                        //为每个客户单独开一个线程处理请求
                        new Thread(new Runnable() {
    
    
                            @Override
                            public void run() {
    
    
                                //客户端得请求   接受客户端得请求  读数据 -- 处理完毕之后将结果相应给客户端 ---写数据到客户端
                                try {
    
    
                                    init(client);//用户的方法  方法里包括了序列化和反序列化
                                } catch (IOException|Exception  e) {
    
    
                                    e.printStackTrace();
                                }
                            }
                        }).start();
                    }
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();
    }

	//接受客户端得请求  读数据 -- 处理完毕之后将结果相应给客户端 ---写数据到客户端
    public void init(Socket client) throws Exception {
    
    
        OutputStream os = null;
        ObjectOutputStream out = null;
        InputStream is = null;
        ObjectInputStream in = null;

        //获取流对象
        try {
    
    
            is = client.getInputStream();
            os = client.getOutputStream();
            out = new ObjectOutputStream(os);
            in = new ObjectInputStream(is);
            //获取客户端得发送得请求类型
            while (true) {
    
    
                System.out.println("用户得请求类型" + flag + "线程" + Thread.currentThread().getName() + "为你服务!");
                
                String flag = in.readUTF();
                System.out.println(flag);
                if ("printAll".equals(flag)) {
    
    
                	//在服务器端打印当前快递存储信息
                    System.out.println("-----------------------------------执行findadll");
                    List<Express> expressList = dao.getExpressList();
                    //获取处理结果 返回给客户端写数据
                    if (expressList != null && expressList.size() != 0) {
    
    
                        System.out.println("----------------当前快递信息如下,准备发给客户端---------------------------");
                        for (Express express : expressList) {
    
    //遍历
                            System.out.println("--" + express);
                        }
                        out.reset();
                        out.writeObject(expressList);
                        System.out.println("发送成功!");
                    } else
                        out.writeObject("快递柜中暂时没有任何快递");
                        out.flush();
                    continue;
                } else if ("insert".equals(flag)) {
    
    
                    //获取客户端发布的参数
                    Express express = (Express) in.readObject();
                    express = dao.add(express);
                    out.writeObject(express);
                    continue;
                } else if ("update".equals(flag)) {
    
    
                    String number =in.readUTF();//旧数据
                    Express newExpress = (Express) in.readObject();
                    boolean res = dao.update(number, newExpress);
                    out.writeObject(res);
                    continue;
                } else if ("delete".equals(flag)) {
    
    
                    String number = in.readUTF();
                    boolean res = dao.delete(number);
                    out.writeObject(res);
                    continue;
                } else if ("findByCode".equals(flag)) {
    
    //取件 先查询后删除
                    Integer code = in.readInt();
                    Express res = dao.findByCodeAndDelete(code);
                    System.out.println("res:"+res);
                    out.writeObject(res);
                    continue;
                } else {
    
    
                    out.writeObject("你的请求服务器暂时处理不了");
                    continue;
                }
            }//end while
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (in != null) {
    
    
                in.close();
            }
            if (out != null) {
    
    
                out.close();
            }
        }
    }//end void

}

Cliente

public class Client {
    
    
    private static Scanner input = new Scanner(System.in);
    private Express express = new Express();
    private final int PORT = 10086;//客户端要链接的端口号
    private Socket client;//客户端

    public static void main(String[] args) {
    
    
        Client c = new Client();
        c.start();
    }
  
    //客户端启动的方法
    public void start() {
    
    
        OutputStream out = null;
        ObjectOutputStream objectOutputStream = null;
        InputStream in = null;
        ObjectInputStream objectInputStream = null;
        //获取流对象
        try {
    
    
            do {
    
    
                if (client == null || client.isClosed()) {
    
    
                    client = new Socket("127.8.0.1", PORT);
                    in = client.getInputStream();
                    out = client.getOutputStream();
                    objectOutputStream = new ObjectOutputStream(out);
                    objectInputStream = new ObjectInputStream(in);
                    System.out.println("客户端连接服务器成功!");
                }
            } while (mainMenu(objectInputStream, objectOutputStream) != 0);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } catch (OutNumberBoundException e) {
    
    
            e.printStackTrace();
        } finally {
    
    //关闭流
            try {
    
    
                if (objectInputStream != null) {
    
    
                    objectInputStream.close();
                }
                if (objectOutputStream != null) {
    
    
                    objectOutputStream.close();
                }
                if (client != null) {
    
    
                    client.close();
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }//end finally
    }//end void start
    
    /**
     * 主菜单,系统界面
     * @return
     */
    public static int mainMenu(ObjectInputStream in, ObjectOutputStream out) throws OutNumberBoundException, Exception {
    
    
        int mainNum = 0;
        do{
    
    
            System.out.println("----------欢迎使用快递管理系统----------");
            System.out.println("请选择您的身份:");
            System.out.println("1.管理员");
            System.out.println("2.普通用户");
            System.out.println("0.退出");
            String s = input.nextLine();
            try{
    
    
                mainNum = validNum(s,0,2);
                break;
            }catch(NumberFormatException | OutNumberBoundException e){
    
    
                System.out.println(e.getMessage());
            }
        }while(true);
        switch(mainNum){
    
    
            case 0://结束使用
                System.out.println("感谢使用快递管理系统!");
                break ;
            case 1://进入管理员平台
                managerPlatform(in,out);
                break ;
            case 2://进入用户平台
                userPlatform(in,out);
                break ;
        }
        return mainNum;
    }//end mainMenu()

    /**
     * 判断输入是否为数字、是否在有效范围内
     * @param s
     * @param begin
     * @param end
     * @return
     * @throws NumberFormatException
     */
    private static int validNum(String s,int begin,int end) throws NumberFormatException, OutNumberBoundException {
    
    
        try{
    
    
            int num = Integer.parseInt(s);
            if (num < begin || num > end){
    
    
                throw new OutNumberBoundException("数字的范围必须在" + begin + "和" + end +"之间");
            }
            return num;
        }catch(NumberFormatException | OutNumberBoundException e){
    
    
            throw new NumberFormatException("输入的必须是数字!");
        }
    }


    /**
     * 管理员操作界面
     * @param in
     * @param out
     * @throws OutNumberBoundException
     * @throws Exception
     */
    public static void managerPlatform(ObjectInputStream in, ObjectOutputStream out) throws OutNumberBoundException, Exception{
    
    
        w:while(true){
    
    
            int managerNum = 0;
            do{
    
    
                System.out.println("尊敬的管理员,您好!");
                System.out.println("请选择您要进行的操作:");
                System.out.println("1.录入快递");
                System.out.println("2.删除快递");
                System.out.println("3.修改快递");
                System.out.println("4.查看所有快递");
                System.out.println("0.返回上一级界面");
                String s = input.nextLine();
                try{
    
    
                    managerNum = validNum(s,0,4);
                    break;
                }catch(NumberFormatException | OutNumberBoundException e){
    
    
                    System.out.println(e.getMessage());
                }
            }while(true);
            switch(managerNum){
    
    
                case 0:{
    
    //返回上一级页面
                    return;
                }
                case 1:{
    
    //1.录入快递
                    insert(in,out);
                }
                break w;
                case 2:{
    
    //2.删除快递
                    delete(in,out);
                }
                break w;
                case 3:{
    
    //3.修改快递
                    update(in,out);
                }
                break w;
                case 4:{
    
    //4.查看所有快递
                    printAll(in,out);
                }
                break w;
            }// end switch
        }//end while
    }//end managerPlatform


    /**
     * 打印所有快递
     * @param in
     * @param out
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static void printAll(ObjectInputStream in, ObjectOutputStream out) throws IOException, ClassNotFoundException {
    
    
        System.out.println("--------当前快递存储情况---------");
        out.writeUTF("printAll");//与Server相对应,发送给服务器请求类型
        out.flush();
        Object obj = in.readObject();
        if (obj instanceof List) {
    
    
            List<Express> expressList = (List<Express>) obj;//强转
            for (Express express : expressList) {
    
    //遍历输出
                System.out.println(express);
            }
        }else {
    
    
            System.out.println(obj);
        }
    }


    /**
     * 添加快递
     * @param in
     * @param out
     */
    private static void insert(ObjectInputStream in, ObjectOutputStream out) {
    
    
        System.out.println("---------存快递----------");
        Express express = new Express();
        System.out.print("请输入快递单号:");
        express.setNumber(input.nextLine());
        System.out.print("请输入快递公司:");
        express.setCompany(input.nextLine());
        //当前快递单号不存在,存快递
        if(Server.dao.findByNumber(express.getNumber()) == -1){
    
    
            try {
    
    
                out.writeUTF("insert");
                out.writeObject(express);
                out.flush();
                //接受服务器端的响应---读数据
                Object object = in.readObject();
                if (object instanceof Express) {
    
    
                    express = (Express) object;
                    System.out.println("添加成功!快递在第" + (express.getX() + 1) + "排,第" + (express.getY() + 1) + "列");
                } else {
    
    
                    System.out.println("添加失败" + object);
                }
            } catch (Exception exception) {
    
    
                System.out.println("系统异常,添加失败!");
                System.out.println(exception.getMessage());
            }
        }else{
    
    
            System.out.println("该快递单号已存在!快递添加失败!");
        }
    }


    /**
     * 删除快递
     * @param in
     * @param out
     */
    private static void delete(ObjectInputStream in, ObjectOutputStream out) {
    
    
        System.out.println("删除快递");
        System.out.print("请输入要删除的快递单号:");
        String number = input.nextLine();
        int exist = Server.dao.findByNumber(number);
        if (exist == -1) {
    
    
            System.out.println("快递不存在!");
        } else {
    
    
            int deleteNum;
            do {
    
    
                System.out.println("是否进行删除操作?");
                System.out.println("1.确认删除");
                System.out.println("0.取消操作");
                String s = input.nextLine();
                deleteNum = -1;
                try {
    
    
                    deleteNum = validNum(s, 0, 1);
                    break;
                } catch (NumberFormatException | OutNumberBoundException e) {
    
    
                    System.out.println(e.getMessage());
                }
            } while (true);
            if (deleteNum == 0) {
    
    
                System.out.println("取消删除成功!");
            } else {
    
    
                try {
    
    
                    out.writeUTF("delete");
                    out.writeUTF(number);
                    out.flush();
                    Object obj = in.readObject();
                    if (obj instanceof Boolean) {
    
    
                        boolean res = (boolean) obj;
                        if (res == true) {
    
    
                            System.out.println("删除成功");
                        } else {
    
    
                            System.out.println("删除失败");
                        }
                    } else {
    
    
                        System.out.println("删除失败!!!!!!");
                    }
                } catch (Exception e) {
    
    
                    System.out.println("系统异常,删除失败!");
                    System.out.println(e.getMessage());
                }
            }// end else  option of delete
        }//end else express exist
    }//end method


    /**
     * 更新快递
     * @param in
     * @param out
     */
    private static void update(ObjectInputStream in, ObjectOutputStream out) {
    
    
        System.out.println("---------修改快递-----------");
        System.out.print("请输入要修改的快递单号:");
        String number = input.nextLine();
        int exist = Server.dao.findByNumber(number);
        if(exist == -1){
    
    
            System.out.println("快递不存在!");
        }else{
    
    
            Express newExpress = new Express();
            System.out.print("请输入新的快递单号:");
            newExpress.setNumber(input.nextLine());
            System.out.print("请输入新的公司名称:");
            newExpress.setCompany(input.nextLine());
            try {
    
    
                out.writeUTF("update");
                out.flush();
                out.writeUTF(number);
                out.flush();
                out.writeObject(newExpress);
                out.flush();
                Object obj = in.readObject();
                if (obj instanceof Boolean) {
    
    
                    boolean res = (boolean) obj;
                    if (res == true) {
    
    
                        System.out.println("更新成功!");
                    } else {
    
    
                        System.out.println("更新失败!");
                    }
                } else{
    
    
                    System.out.println("更新失败!!!!!!");
                }
            } catch (Exception e) {
    
    
                System.out.println("系统异常,更新失败!");
                System.out.println(e.getMessage());
            }
        }// end else(option of exist then update)
    }//end update method


    /**
     * 用户操作界面
     * @throws OutNumberBoundException
     * @throws Exception
     */
    public static void userPlatform(ObjectInputStream in, ObjectOutputStream out) throws OutNumberBoundException, Exception {
    
    
        int code = -1;
        do {
    
    
            System.out.print("请输入取件码:");
            String s = input.nextLine();
            try {
    
    
                code = validNum(s, 100000, 999999);
                break;
            } catch (NumberFormatException | OutNumberBoundException e) {
    
    
                System.out.println(e.getMessage());
            }
        } while (true);
        out.writeUTF("findByCode");
        out.writeInt(code);
        out.flush();
        Object obj = in.readObject();
        if (obj instanceof Express) {
    
    
            Express e = (Express) obj;
            System.out.println("快递信息:" + e);
            System.out.println("您的快递存储在快递柜的第" + (e.getX() + 1) + "排,第" + (e.getY() + 1) + "列,取件愉快~");

        } else {
    
    
            System.out.println("快递不存在,取件失败!");
        }
    }
    
}

Supongo que te gusta

Origin blog.csdn.net/m0_50609545/article/details/120090680
Recomendado
Clasificación