课程: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的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果
运行截图
实验截图
客户端
服务器