Express 管理コンソールの簡易バージョン - マルチスレッドおよびネットワーク プログラミングの追加 (完全バージョン、完全なソース コードが添付) (Java)


アレイストレージのバージョンについては、 Express管理コンソール簡易版 - アレイストレージ版(Java)の記事を参照してください。

リストコレクション保存版については、Express管理コンソール簡易版 - リストコレクション保存版(Java)を参照してください。

マップコレクション保存版については、Express管理コンソール簡易版 - マップコレクション保存版(Java)を参照してください。

IO テクノロジを使用して、マップ コレクション ストレージ バージョンに基づくデータ ストレージを実装する方法については、次の記事を参照してください: Express 管理コンソールの簡易バージョン - IO ストリームの使用 (Java)

  • アレイ ストレージのバージョンでは、二次元配列速達を格納するには、速達の位置が 2 次元配列の 2 つの添字に対応します。

  • リストコレクション保存版採用リストコレクションストア速達配送

  • マップコレクション保存版採用地図コレクションMap コレクションを使用して速達を保存する利点は、 Map がキーと値のペアであり、キーが速達番号、値が速達オブジェクトであるため、速達番号が確実に一意であることです。

  • IO ストリームの使用は、 マップ コレクションのストレージ バージョンに基づいて最適化されています。IO テクノロジは、高速データをファイルに保存し、ファイルからデータを読み取るために使用されます。ファイルに高速情報が保存された後は、アプリケーションが実行されるたびにファイルから情報を読み取ることができます。番組データが常に存在するようにコンテンツ

  • マルチスレッドとネットワークプログラミングに関しては、クライアントとサーバー間のデータ対話を実現するためにマルチスレッドとネットワークプログラミングテクノロジーが追加されており、マルチスレッドを使用して、各ユーザーがサーバーにログインリクエストを送信した後、サーバーが割り当てを行います。リクエストを処理するスレッド。


特定の要件

  1. ネットワークプログラミングモードに基づいてユーザーログイン機能を実装し、ユーザー情報の取得に使用されるクライアントと、データの保存や論理判断に使用されるサーバーの概念を理解します
  2. ネットワークプログラミングに基づいて、サーバー側でマルチスレッドモードが有効になり、各ユーザーはサーバーにログインリクエストを送信する必要があり、サーバー側はリクエストを処理するスレッドを割り当て、サーバーサイドマルチでのユーザーログインを実現します。 -スレッドモード。

ナレッジポイントの関与

  1. オブジェクト指向
  2. 集める
  3. IO
  4. マルチスレッド化
  5. ネットワークプログラミング

アイデアとコードの実装

1. カスタム例外

例外パッケージを作成し、新しいクラス OutNumberBoundException を作成します。

OutNumberBoundException

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

2. ツールキット

util パッケージを作成し、新しいクラス IOUtil を作成します。

IOUまで

ファイルの読み取りおよび書き込みツール クラスなので、静的メソッドを推奨します

  • 指定されたファイルからデータを読み取ります
public static Object readFile(String fileName) throws IOException, ClassNotFoundException {
    
    
        FileInputStream fis = new FileInputStream(fileName);//指定文件
        ObjectInputStream ois = new ObjectInputStream(fis);
        return ois.readObject();//读出数据
    }
  • 指定したファイルにデータを書き込みます
 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. オブジェクト

pojo パッケージを作成し、新しいクラス Express を作成します

急行

  • プロパティを定義し、setter と getter を使用して値を設定および取得する
	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;
    }
  • パラメーターなしおよびフルパラメーターのコンストラクターを定義する
/**
     * 定义无参构造方法
     */
    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;
    }
  • toString をオーバーライドして情報を文字列に変換します
    /**
     * toString将信息转化为字符串形式
     */
    @Override
    public String toString() {
    
    
        return "快递信息[" +
                "快递单号:" + getNumber() + ' ' +
                ", 快递公司:" + getCompany() + ' ' +
                ", 取件码:" + getCode() + " , 在第" + (getX() + 1) + "行 第" + (getY() + 1) + "列柜子" +
                ']';
    }

4. データ処理

Dao パッケージを作成し、新しいクラス Dao を作成します

ダオ

  • ファイルの作成とデータの初期化
    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());
        }
    }
  • 宅配業者を追加
    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;
    }

  • 現在の場所に宅配業者がすでに存在するかどうかを確認する
    public static boolean isExist(int x, int y) {
    
    
        for (Express express : expressList) {
    
    
            if (express.getX() == x && express.getY() == y) {
    
    
                return true;
            }
        }
        return false;
    }
  • ランダムに生成されたピックアップ コードが存在するかどうかを確認する
    public static boolean isExistCode(int code) {
    
    
        for (Express express : expressList) {
    
    
            if (express.getCode() == code) {
    
    
                return true;
            }
        }
        return false;
    }
  • エクスプレスの削除
    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;
    }
  • 速達番号に基づいて速達をクエリする
    public static int findByNumber(String number) {
    
    
        int i = 0;
        for (Express express : expressList) {
    
    
            if (number.equals(express.getNumber())) {
    
    
                return i;
            }
            i++;
        }
        return -1;
    }
  • アップデートエクスプレス
    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;
    }
  • すべての配送業者情報を取得する
    public static List<Express> getExpressList() {
    
    
        return expressList;
    }
  • 宅配便を受け取る
    public Express findByCodeAndDelete(int code) throws Exception {
    
    
        Express express = findExpressByCode(code);
        if (express!=null){
    
    
            if (delete(express.getNumber())){
    
    
                return express;
            }
        }
        return null;
    }
  • 集荷コードで宅配業者を探す
    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. C/Sネットワークプログラミング

  • 主にサーバーとクライアント間の対話を担当します

ソケット パッケージを作成し、新しいクラスのサーバーとクライアントを作成する

サーバーサーバー

mainでServerオブジェクトを作成し、startメソッドを呼び出します。

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

次に、サーバーを起動するための start メソッドを記述します。


まずサーバーを作成します

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

1. サーバーをセットアップして実行し、クライアントに接続するための開始メソッドを作成します。

  • サーバーに入ったら、クライアントの接続を待ち、
    while ループを使用してユーザーからの複数の接続を実現します。
	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();

start() メソッドの完全なコードは次のとおりです。

    //开启一个线程 服务端开启的方法
    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. タスク実行で init メソッドを記述し、クライアント データと対話します。

  • メッセージを受信する
        InputStream is = null;
        ObjectInputStream in = null;
  • メッセージを送る
        OutputStream os = null;
        ObjectOutputStream out = null;
  • ストリームオブジェクトを取得する
		is = client.getInputStream();
    	os = client.getOutputStream();
   		out = new ObjectOutputStream(os);
    	in = new ObjectInputStream(is);
  • システムに入る
       System.out.println("用户得请求类型" + flag + "线程" + Thread.currentThread().getName() + "为你服务!");
  • ユーザーの特定の操作を取得する
		String flag = in.readUTF();
		System.out.println(flag);
    • 宅配業者を追加
                    //获取客户端发布的参数
                    Express express = (Express) in.readObject();
                    express = dao.add(express);
                    out.writeObject(express);
    • エクスプレスの削除
                    String number = in.readUTF();
                    boolean res = dao.delete(number);
                    out.writeObject(res);
    • 速達便の変更
                    String number =in.readUTF();//旧数据
                    Express newExpress = (Express) in.readObject();
                    boolean res = dao.update(number, newExpress);
    • すべての出荷を印刷する
                	//在服务器端打印当前快递存储信息
                    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();
    • 選び出す
                    Integer code = in.readInt();
                    Express res = dao.findByCodeAndDelete(code);
                    System.out.println("res:"+res);
                    out.writeObject(res);
  • ストリームを閉じる
		if (in != null) {
    
    
			in.close();
			}
        if (out != null) {
    
    
            out.close();
        }

init メソッドの完全なコードは次のとおりです。

	//接受客户端得请求  读数据 -- 处理完毕之后将结果相应给客户端 ---写数据到客户端
    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

クライアント クライアント

main でClient オブジェクトを作成し、start メソッドを呼び出して、ユーザーがサーバーに接続できるようにします。

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

まずクライアントを作成します

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

1. 開始メソッドを作成し、クライアントを実行して、サーバーに接続します。

  • メッセージを受信する
        InputStream is = null;
        ObjectInputStream in = null;
  • メッセージを送る
        OutputStream os = null;
        ObjectOutputStream out = null;
  • サーバーに接続する
            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);
  • システムを終了し、ストリームを閉じる
		if (objectInputStream != null) {
    
    
			objectInputStream.close();
		}
	    if (objectOutputStream != null) {
    
    
			objectOutputStream.close();
	    }
		if (client != null) {
    
    
			client.close();
		}

完全な開始方法は次のとおりです。

    //客户端启动的方法
    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. メインメニュー

    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()
  • 入力が有効な数値かどうかを判断します
    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 管理者インターフェース

    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

  • 宅配業者を追加
    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("该快递单号已存在!快递添加失败!");
        }
    }
  • エクスプレスの削除
    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
  • 速達便の変更
    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
  • すべての出荷を印刷する
    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 ユーザーインターフェース

  • 選び出す
    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("快递不存在,取件失败!");
        }
    }

完全なコード

1. カスタム例外

OutNumberBoundException

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

2. ツールキット

IOUまで

/**
 * 文件读写技术
 *
 */
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. オブジェクト

急行

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. データ処理

ダオ

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. C/Sネットワークプログラミング

サーバ

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

}

クライアント

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("快递不存在,取件失败!");
        }
    }
    
}

おすすめ

転載: blog.csdn.net/m0_50609545/article/details/120090680