課程:Java程序設計 班級:1652班 姓名:賈普涵 學號:20165204java
指導教師:婁嘉鵬 實驗日期:2018年5月28日算法
實驗時間:13:45 - 15:25express
實驗序號:實驗五編程
實驗名稱:網絡編程與安全數組
實驗內容:安全
一、掌握Java Socket的相關內容;服務器
二、學會創建客戶端與服務器端之間的聯繫;網絡
三、學習並應用密碼學的相關內容socket
MyBC學習
import java.io.IOException; import java.util.Scanner; import java.util.Stack; public class MyBC { Stack MyStack; String expression; //原來的中綴 String result = ""; //做爲結果的後綴 MyBC(String in) { expression = in; MyStack = new Stack(); } public String turnInto() { for (int j = 0; j < expression.length(); j++) { char ch = expression.charAt(j); switch (ch) { case '+': gotOper(ch, 1); break; case '-': gotOper(ch, 1); break; case '*': gotOper(ch, 2); break; case '/': gotOper(ch, 2); break; /*讀到左括號壓棧*/ case '(': MyStack.push(ch); break; /*讀到右括號,把與最近的一個左括號之間的東西彈出而後加進字符串裏*/ case ')': dumpOut(ch); break; /*爲保證後綴表達式的完整讀到數字不輸出,加到後綴表達式結果的字符串裏*/ /*添個空格*/ default: result = result + " " +ch; break; } } /*若是棧裏還有東西,加到字符串末尾*/ while (!MyStack.empty()) { result = result + " "+MyStack.pop(); } /*字符串result就是所求的後綴表達式*/ return result; } /*比較運算符和棧頂元素的優先級*/ public void gotOper(char opThis, int priotityLevel) { while (!MyStack.empty()) { /*獲得棧頂,可是彈出了的類型是Object須要強轉爲char*/ char opTop = (char) MyStack.pop(); if (opTop == '(') { /*棧頂是左括號轉到63行,把下一個運算符(onThis)壓棧*/ MyStack.push(opTop); break; } else { /*獲得棧頂符號的優先級,記錄在x*/ int x; /*加減優先級置1,乘除優先級置2*/ if (opTop == '+' || opTop == '-') { x = 1; } else { x = 2; } /*處理棧頂的操做符,低優先級壓回,高優先級加進結果的字符串result*/ if (x < priotityLevel) { MyStack.push(opTop); break; } else { /*加個空格,再加上棧頂*/ result = result +" "+ opTop; } } } /*退不退棧頂,最後這個都進棧*/ MyStack.push(opThis); } public void dumpOut(char ch) { while (!MyStack.empty()) { char chx = (char) MyStack.pop(); //強轉爲char if (chx == '(') { break; } else { /*加空格*/ result = result +" "+ chx; } } } public static void main(String[] args) throws IOException { Scanner reader = new Scanner(System.in); String i = reader.nextLine(); String output; MyBC theTrans = new MyBC(i); output = theTrans.turnInto(); MyDC ltlAndJph = new MyDC(); int resultNumber = ltlAndJph.evaluate(output); //計算結果 System.out.println("後綴結果: " + output); System.out.println("計算結果: " + resultNumber); } }
MyDC
import java.util.Stack; import java.util.StringTokenizer; public class MyDC { /** * constant for addition symbol */ private final char ADD = '+'; /** * constant for subtraction symbol */ private final char SUBTRACT = '-'; /** * constant for multiplication symbol */ private final char MULTIPLY = '*'; /** * constant for division symbol */ private final char DIVIDE = '/'; /** * the stack */ private Stack<Integer> stack; /** * 18 * Sets up this evalutor by creating a new stack. * 19 */ public MyDC() { stack = new Stack<Integer>(); } public int evaluate(String expr) { int op1, op2, result = 0; String token; StringTokenizer tokenizer = new StringTokenizer(expr); while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); if (isOperator(token)) { op2 = (stack.pop()).intValue(); op1 = (stack.pop()).intValue(); result = evalSingleOp(token.charAt(0), op1, op2); stack.push(new Integer(result)); } else { stack.push(new Integer(Integer.parseInt(token))); } } return result; } private boolean isOperator(String token) { return (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")); } private int evalSingleOp(char operation, int op1, int op2) { int result = 0; switch (operation) { case ADD: result = op1 + op2; break; case SUBTRACT: result = op1 - op2; break; case MULTIPLY: result = op1 * op2; break; case DIVIDE: result = op1 / op2; } return result; } }
實驗截圖
基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
客戶端讓用戶輸入中綴表達式,而後把中綴表達式調用MyBC.java的功能轉化爲後綴表達式,把後綴表達式經過網絡發送給服務器
服務器接收到後綴表達式,調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
客戶端顯示服務器發送過來的結果
Server(由結對夥伴負責)
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /*5207 負責服務器*/ public class Server { public static void main(String[] args) { String s; //s是接收過來的後綴表達式的字符串 ServerSocket serverForClient = null; Socket socketOnServer = null; DataOutputStream out = null; DataInputStream in = null; try{ serverForClient = new ServerSocket(2010); //與客戶端的2010端口一致 } catch(IOException e1){ System.out.println(e1); } try{ System.out.println("等待客戶呼叫"); socketOnServer = serverForClient.accept(); out = new DataOutputStream(socketOnServer.getOutputStream()); in = new DataInputStream(socketOnServer.getInputStream()); /*接收後綴表達式*/ String i = in.readUTF(); /*計算後綴表達式的值*/ MyDC ltlAndJph = new MyDC(); int resultNumber = ltlAndJph.evaluate(i); //計算結果 System.out.println("在李天林負責的服務器端,計算的結果是:"+resultNumber); Integer I = new Integer(resultNumber); s = I.toString(); /*把計算結果以字符串的形式發送給客戶端*/ out.writeUTF(s); } catch(Exception e){ System.out.println("客戶已斷開"+e); } } }
Client(由我負責)
import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Scanner; /*5204 負責客戶端*/ public class Client { public static void main(String[] args) { String s; Socket mysocket; DataInputStream in = null; DataOutputStream out = null; try { mysocket = new Socket("127.0.0.1",2010); in = new DataInputStream(mysocket.getInputStream()); out = new DataOutputStream(mysocket.getOutputStream()); /*讓用戶輸入中綴表達式*/ System.out.println("當前爲客戶端,請輸入中綴表達式"); Scanner reader = new Scanner(System.in); String i = reader.nextLine(); /*把中綴表達式調用MyBC.java的功能轉化爲後綴表達式*/ MyBC turn = new MyBC(i); s = turn.turnInto(); //s是後綴結果,須要發送給服務器 System.out.println("在客戶端求得後綴表達式:"+s); /*把後綴表達式經過網絡發送給服務器*/ out.writeUTF(s); //把s寫過去 /*客戶端接收計算的結果*/ String get = in.readUTF(); System.out.println("賈普涵負責的客戶端接收到的計算結果是:"+get); } catch(Exception e){ System.out.println("服務器已斷開"); } } }
實驗截圖
客戶端讓用戶輸入中綴表達式,而後把中綴表達式調用MyBC.java的功能轉化爲後綴表達式,把後綴表達式用3DES或AES算法加 密後經過網絡把密文發送給服務器
服務器接收到後綴表達式表達式後,進行解密(和客戶端協商密鑰,能夠用數組保存),而後調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
客戶端顯示服務器發送過來的結果
運行截圖
實驗截圖
客戶端
服務器