First, express management training tasks
1. Description of the topic
Remember the old days of delivery management?
We store data in files, in fact, data storage in the client end is very insecure, today we will learn network programming, the client end is only used to collect user operations, the need to store data are stored in the server.
To ensure that the server can connect to multiple clients at the same time, remember to introduce multithreading technology to the server. Come on and learn!
2. Source code
The code structure
2.1 bean. Express
package bean; import java.io.Serializable; import java.util.Objects; /** * */ public class Express implements Serializable { private String number; Private String company; // private int code; Public int posX, posY; Public Express(String number, String company, int code) {this.number = number; this.company = company; this.code = code; } public Express() { } // getter/setter public String getNumber() { return number; } public String getCompany() { return company; } public int getCode() { return code; } public void setNumber(String number) { this.number = number; } public void setCompany(String company) { this.company = company; } public void setCode(int code) { this.code = code; @override public String toString() {return "Express{" + "number='" + number + '\' + ", company='" + company + '\'' + ", code=" + code + '}'; @override public Boolean equals(Object o) {if (this == o) {if (this == o) {if (this == o); return true; if (o == null || getClass() ! = o.getClass()) return false; Express express = (Express) o; return Objects.equals(number, express.number); } @Override public int hashCode() { return Objects.hash(code); }}Copy the code
2.2 the dao. ExpressDao
package dao; import bean.Express; import java.io.*; import java.util.ArrayList; import java.util.Random; Public class ExpressDao {private File File = new File(" serializeddata.txt "); private boolean[][] cabinet = new boolean[10][]; Private ArrayList<Express> discover = new ArrayList<>(); Private Random Random = new Random(); /** * deserialize the object stored in the container HashMap<Integer, Express> data */ public void readFromFile() { try (FileInputStream fis = new FileInputStream(file)) { ObjectInputStream ois = new ObjectInputStream(fis); expresses = (ArrayList<Express>) ois.readObject(); // deserialize the read object ois.close(); / / close the input stream} the catch (IOException | ClassNotFoundException e) {expresses = new ArrayList < Express > (); ** * serialize the storage object HashMap<Integer, Express> data * @throws IOException */ public void writeToFile() throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); oos.writeObject(expresses); Oos. Close (); } /** * initialize data structures: cabinet (表 达), discover (表 达) */ public void init() {for(int I = 0; i < 10; i++){ cabinet[i] = new boolean[10]; } for(Express e : expresses) { cabinet[e.posX][e.posY] = true; }} /** ** @param e Newly added Express object * @return */ public synchronized Boolean add(Express e){int size = expresses.size(); if(size >= 100){ return false; } // 1, int x = -1, y = -1; while (true){ x = random.nextInt(10); y = random.nextInt(10); if(cabinet[x][y] == false){ break; Int code = randomCode(); // get e.setcode (code) without duplicates; e.posX = x; // e.posy = y; size++; // Cabinet [x][y] = true; // This location has been occupied. Discover (e); // return true; } @return */ private int randomCode(){while (true) {int code = random.nextint (900000) + 100000; // Range (000000-899999)+1000000 Express e = findByCode(code); If (e == null) {return code is not repeated; @param number * @return */ public findByNumber(String number){public findByNumber(String number){ for(Express e : expresses) { if(e.getNumber().equals(number)) { return e; } } return null; } public findByCode(int code){public findByCode(int code){public findByCode(int code){public findByCode(int code); expresses) { if(e.getCode() == code) { return e; } } return null; } @param oldExpress @param newExpress */ public synchronized Boolean update(Express oldExpress, Express newExpress){ delete(oldExpress); return add(newExpress); } @param e */ public synchronized Boolean delete(Express e){cabinet[e.posx][e.posy] = false; return expresses.remove(e); Public synchronized ArrayList<Express> getAll() {find entertainment; }}Copy the code
2.3 the main
1)main.ClientMain
package main; import bean.Express; import view.View; import java.io.*; import java.net.Socket; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ClientMain { private Socket socket; private View v = new View(); public static void main(String[] args) throws IOException { ClientMain client = new ClientMain(); client.link(); } /** * create a socket to connect to the server; * Create object input/output streams for data interaction with the server; * @throws IOException */ public void link() throws IOException { OutputStream os = null; InputStream is = null; ObjectOutputStream oos = null; ObjectInputStream ois = null; Try {socket = new socket ("127.0.0.1", 8888); v.connectSuccess(); is = socket.getInputStream(); os = socket.getOutputStream(); oos = new ObjectOutputStream(os); Ois = new ObjectInputStream(is); o:while (true) { int num = v.menu(); // Get the role selection code oos. WriteInt (num); oos.flush(); switch (num) { case 0: break o; case 1: gClient(oos, ois); break; case 2: uClient(oos, ois); break; default: v.choiceError(); break; } } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } finally { if(ois ! = null) ois.close(); if(oos ! = null) oos.close(); if(socket ! = null) socket.close(); }} /** * Client administrator module * @param oos * @param ois * @throws IOException * @throws ClassNotFoundException */ public void gClient(ObjectOutputStream oos, ObjectInputStream ois) throws IOException, ClassNotFoundException { while (true) { int num = v.gMenu(); // Get oos. WriteInt (num); // Send the function code to the server to ensure access to the same function module oos. Flush (); Switch (num) {case 0:// Exit return; Case 1:// Insert (oos, ois); break; Case 2:// Modify update(oos, ois); break; Case 3:// delete delete(oos, ois); break; Case 4:// Display all printAll(oos, ois); break; default: v.choiceError(); break; }} /** * Client user module * @param oos * @param ois * @throws IOException * @throws ClassNotFoundException */ public void uClient(ObjectOutputStream oos, ObjectInputStream ois) throws IOException, ClassNotFoundException { while (true) { int num = v.uMenu(); oos.writeInt(num); oos.flush(); switch (num) { case 0: return; case 1: int code = v.getExpress(); oos.writeInt(code); oos.flush(); Express e = (Express) ois.readObject(); if(e ! V. printExpress(e); if(ois.readBoolean()) v.success(); else v.fail(); } else { v.printNull(); } break; default: v.choiceError(); break; }}} /** * insert the express object; * Use the View object to get the express object to be inserted, Pass it to the server * @param oos * @param ois * @throws IOException * @throws ClassNotFoundException */ public void insert(ObjectOutputStream oos, ObjectInputStream ois) throws IOException, ClassNotFoundException { Express e = v.insert(); oos.writeObject(e); oos.flush(); Express e1 = (Express) ois.readObject(); If (e1 == null) {if(ois.readBoolean()) {// Insert successfully v.scuccess (); } else { v.fail(); } } else { v.expressExist(); }} /** * delete the express object * @param oos * @param ois * @throws IOException * @throws ClassNotFoundException */ public void delete(ObjectOutputStream oos, ObjectInputStream ois) throws IOException, ClassNotFoundException { String id = v.findByNumber(); oos.writeObject(id); oos.flush(); Express e = (Express) ois.readObject(); if(e ! = null) { int num = v.delete(); // Check again with the user whether oos. WriteInt (num) should be removed; oos.flush(); Switch (num) {case 1:// Confirm delete if(ois.readBoolean()) v.scuccess (); else v.fail(); break; Default :// Cancel delete or exit break; } } else { v.printNull(); }} /** * Update the express object * @param oos * @param ois * @throws IOException * @throws ClassNotFoundException */ public void update(ObjectOutputStream oos, ObjectInputStream ois) throws IOException, ClassNotFoundException { String id = v.findByNumber(); oos.writeObject(id); oos.flush(); Express e = (Express) ois.readObject(); if(e ! = null) {// The updated object exists Express e1 = v.update(); oos.writeObject(e1); oos.flush(); if(ois.readBoolean()) v.success(); else v.fail(); } else { v.printNull(); }} /** * Print the express object * @param oos * @param ois * @throws IOException * @throws ClassNotFoundException */ public void printAll(ObjectOutputStream oos, ObjectInputStream ois) throws IOException, ClassNotFoundException { // ArrayList<Express> expresses = (ArrayList<Express>) ois.readObject(); // v.printAll(expresses); Express[] es = (Express[]) ois.readObject(); List<Express> expresses = Arrays.asList(es); v.printAll(expresses); }}Copy the code
2)main.ServerMain
package main; import bean.Express; import dao.ExpressDao; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class ServerMain { private ServerSocket serverSocket; private ExpressDao dao = new ExpressDao(); private int numOfClient = 0; // Server public static void main(String[] args) throws IOException {ServerMain server = new ServerMain(); server.start(); */ public void start() {try {serverSocket = new serverSocket (8888); */ public void start() {try {serverSocket = new serverSocket (8888); System.out.println(" Server started "); dao.readFromFile(); // Read data from a file dao.init(); // Initialize the data structure system.out.println (" initialization succeeded "); while (true) { Socket socket = serverSocket.accept(); System.out.println(" + (++numOfClient) + "); new Thread() { @Override public void run() { try { receive(socket); } catch (IOException e) {e.printStackTrace(); } } }.start(); } } catch (IOException e) { e.printStackTrace(); } finally { try { if(serverSocket ! = null){ serverSocket.close(); } } catch (IOException e) { e.printStackTrace(); }}} /** * Create an object input/output stream to interact with the client; * Enter the main module and select the role; * @param socket * @throws IOException */ public void receive(Socket socket) throws IOException { InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); ObjectInputStream ois = new ObjectInputStream(is); ObjectOutputStream oos = new ObjectOutputStream(os); try(is; os; ois; O: while (true) {switch (ois.readint ()) {case 0:// Exit dao.writetofile (); // Write the data object back to the file break o; case 1: gClient(ois, oos); // Enter the administrator operation function module break; case 2: uClient(ois, oos); // Enter the user operation function module break; default: break ; } } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }} /** * server -- admin module, Responsible for data interaction with the client - administrator module * @param ois * @Param oos * @throws IOException * @throws ClassNotFoundException */ public void gClient(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException {while (true) {switch (ois.readint ()) {case 0:// Exit return; Case 1:// Insert insert(ois, oos); break; Case 2:// Modify update(ois, oos); break; Case 3:// delete delete(ois, oos); break; Case 4:// display all printAll(ois, oos); break; }}} /** * server -- user module, * @param ois * @param oos * @throws IOException */ public void uClient(ObjectInputStream ois, ObjectOutputStream oos) throws IOException { while (true) { switch (ois.readInt()) { case 0: return; Case 1:// Express e = dao.findByCode(oi.readint ()); Oos. WriteObject (e); // Pass the lookups to the client oos. Flush (); if(e ! = null) { oos.writeBoolean(dao.delete(e)); oos.flush(); } break; default: break; }}} /** * insert the express object; * Accept the new express object sent by the client, operate the data with DAO object, Return the operation result to the client * @param ois * @Param oos * @ioException * @throws ClassNotFoundException */ public void insert(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException { Express e = (Express) ois.readObject(); Express e1 = dao.findByNumber(e.getNumber()); // Determine whether oos exists in the corresponding express according to the tracking number. WriteObject (E1); oos.flush(); if(e1 == null) { oos.writeBoolean(dao.add(e)); oos.flush(); }} /** * delete the express object * @param ois * @param oos * @ioException * @throws ClassNotFoundException */ public void delete(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException { String id = (String) ois.readObject(); Express e = dao.findByNumber(id); oos.writeObject(e); oos.flush(); if(e ! = null) {// The express object exists switch (ois.readint ()) {// Confirm again to the user whether to delete case 1: oos. WriteBoolean (dao.delete(e)); oos.flush(); break; default: break; }} /** * Update express object * @param ois * @param oos * @throws IOException * @throws ClassNotFoundException */ public void update(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException { String id = (String) ois.readObject(); Express e = dao.findByNumber(id); oos.writeObject(e); oos.flush(); if(e ! = null) { Express e1 = (Express) ois.readObject(); oos.writeBoolean(dao.update(e, e1)); oos.flush(); @param ois * @param oos * @throws IOException */ public void printAll(ObjectInputStream ois, ObjectOutputStream oos) throws IOException { // oos.writeObject(dao.getAll()); // oos.flush(); ArrayList<Express> list = dao.getAll(); Express[] expresses = new Express[list.size()]; list.toArray(expresses); oos.writeObject(expresses); oos.flush(); }}Copy the code
2.4 the view. The view
package view; import bean.Express; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Scanner; Public class View {public Scanner input = new Scanner(system.in); */ public int menu(){system.out.println (" Enter the function number as prompted: "); System.out.println("1, administrator "); System.out.println("2, common user "); System. The out. Println (" 0, exit "); String s = input.nextLine(); int funcNum = -1; try{ funcNum = Integer.parseInt(s); }catch (NumberFormatException e){return menu(); } the if (funcNum < 0 | | funcNum > 2) {/ / function code is not a legal return menu (); } return funcNum; } / * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * * * * / / get the administrator the function of the input code * @ the legal function of return administrator input code 1: */ public int gMenu(){system.out.println (" Input function number as prompted: "); System.out.println("1, express input "); System.out.println("2, "); System.out.println("3, express delete "); System.out.println("4, view all packages "); System. The out. Println (" 0, exit "); String s = input.nextLine(); int funcNum = -1; try{ funcNum = Integer.parseInt(s); }catch (NumberFormatException e){return gMenu(); } the if (funcNum < 0 | | funcNum > 4) {/ / function code is not a legal return gMenu (); } return funcNum; Public Express insert(){system.out.println (" please input the Express information as required: "); System.out.print(" Please input Courier number: "); String number = input.nextLine(); System.out.print(" please input express company: "); String company = input.nextLine(); Express e = new Express(); e.setNumber(number); e.setCompany(company); return e; } /** * 2 public Express update(){system.out.print (" please input a new Express number: "); String number = input.nextLine(); System.out.print(" Please input new express company "); String company = input.nextLine(); Express e = new Express(); e.setNumber(number); e.setCompany(company); return e; */ public int delete(){system.out.println (" confirm whether to delete: "); System.out.println("1, confirm delete "); System.out.println("2, undelete "); System. The out. Println (" 0, exit "); String s = input.nextLine(); int num = -1; try { num = Integer.parseInt(s); }catch (NumberFormatException e){ return delete(); } if(num < 0 || num > 2){ return delete(); } return num; Public void printAll(List<Express> es){int count = 0; for(Express e : es) { count++; printExpress(e); } if(count == 0){system.out.println (); }} /** * public String findByNumber(){system.out.println (" Please input the information as required: "); System.out.print(" Please input the Courier number to operate: "); String number = input.nextLine(); return number; } @param e */ public void printExpress(Express e){if(e == null){system.out.println (" Express e does not exist "); return; } system.out. println(" express info: "); System. Out.println (" position: the first "+ (e.p osX + 1) +", "+ (e.p osY + 1) +"; + LLDB company () + LLDB company (); + LLDB number () + LLDB number () + "; + LLDB: + LLDB () + ";" ); } / * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * * * * / / get the user input the code (simplified here, as long as the same piece of code, */ public int uMenu(){system.out.println (" input function number as required: "); System. The out. Println (" 0, exit "); System.out.println("1, "); String s = input.nextLine(); int funcNum = -1; try{ funcNum = Integer.parseInt(s); }catch (NumberFormatException e){system.out.println (" formatException "); return uMenu(); } the if (funcNum < 0 | | funcNum > 1) {/ / function code is not a legal System. The out the println (" function code illegal "); return uMenu(); } return funcNum; } /** * @return */ public int getExpress() {system.out.println (); System.out.print(" Please enter the fetch code: "); String s = input.nextLine(); int code = -1; try{ code = Integer.parseInt(s); }catch (NumberFormatException e){system.out.println (" formatException "); return getExpress(); } the if (code < 100000 | | code > 999999) {/ / function code is not a legal System. The out the println (" input is wrong, please try again!" ); return getExpress(); } return code; } public void expressExist(){system.out.println (system.out.println); } public void printCode(Express e) {system.out.println () + LLDB (); } public void success(){system.out.println (" ); } public void fail(){system.out.println (" operation failed! ); } public void choiceError() {system.out.println (); ); } public void printNull(){system.out.println (); } public void connectSuccess() {system.out.println (" connectSuccess "); }}Copy the code
3,
There are major changes compared to the last mission card @& Goodbye Firefly & mission Card _03-Java Core Class Library section 4 IO.
3.1 Core data structure changes
Delete HashMap<Integer, Express> data to find only Collection entertainment.
- Although it is possible to quickly find Express objects based on HashMap, repetitive storage of Express objects will be caused. In other words, many repetitive Express objects are stored in data and discover. Therefore, only the Express data structure is retained in this modification.
The data store is moved from the main function to the DAO object.
- The data is stored in main, and a large number of parameters need to be transferred to operate the data using DAO objects, which makes the function seem jumbled.
- The main function declares a large number of data structures, which makes the main function look complicated and destroys the overall sense of structure clarity.
3.2 ExpressDao
1) Store all the express object data in a dao property (the last IO task card put them in the main method);
2) Cancel the HashMap data structure to find the express object according to the pickup code, and replace it with ArrayList storage. Avoid object repeated storage occupies a large amount of space.
3) Insert, delete, update, query all and other methods are modified with synchronized to ensure thread safety;
3.3 Main, ServerMain and ClientMain
1) Split Main into ServerMain and ClientMain methods, with one responsible for the server and the other for the client;
2) The client and the server need to ensure roughly the same logical structure, that is, when the client changes from state 1 to state 2 (changes in method functions, data objects and types accepted, etc.), the server needs to listen for this state change and perform the same state transition operation. And vice versa;
3) The data exchange between the client and the server is once and for all, strictly matching! Be consistent even with new input and output streams!
4) Server start special declaration of a start method to complete, the main role is: create ServerSocket, deserialize read object information, initialize data structure, through the while loop to achieve multi-threading, thread run method only to call receive method (into the role selection module);
5) The receive on the server and the Link on the client are paired with each other. Ois (ObjectInoutStream) and OOS (ObjectOutputStream) are created in these two methods and taken as parameters for data interaction;
3.4 illustrates
The realization of multithreading, collection, IO and other technologies;
Better method design, making the overall structure of the project clear, low redundancy;
Basically complete the function required by the topic: serialization deserialization, multithreading, collection, etc.;
3.5 Problems encountered
1) The client is stuck on getting the ObjectInputStream and does not proceed further
After consulting the teacher, found the problem. Server and client in the data transmission, not only need to pair in the interaction stage, declaration assignment also need to pair, that is, output corresponds to input, input corresponds to output!
2) After the data was manipulated in the DAO, the express object set did change (printed out on the server). But when you do printAll on the client, the first printAll is correct, and no matter how you change it, the second printAll is not going to change, right
The comment out is the original problem code. The content of the collection object passed between the client and server by means of the stream has not been changed. It is still the data transferred for the first time, so the result will not be changed.
But two questions :(check back later)
- Isn’t the purpose of flush clear buffers? Why doesn’t it work?
- Why would transferring an ArrayList object into an array of objects solve the problem? Is it because the server renews the array every time it transfers?
3.6 thinking
1) What are the advantages and disadvantages of a try/catch as opposed to throwing an exception directly?
2) Pass the stream as a parameter, call the method many times and get the data transmitted in the stream as the first time, no matter what operation is performed on the original data? So what does flush mean?
3) When the server and client interact with each other, this rule is followed not only when data is transmitted once and for all, but also when ois (ObjectInoutStream) and OOS (ObjectOutputStream) are created
The chapters are summarized here (the better we understand you guys, the better we understand you guys).
Have a question welcome to ask, everyone together in learning Java on the road to play strange upgrade! (O ゜ – ゜▽゜)