2018-2019-2 20175304 实验五《网络编程与安全》实验报告
一、实验报告封面
课程:Java程序设计 班级:1753班 姓名:刘朝尹 学号:20175304
指导教师:娄嘉鹏 实验日期:2019年5月31日
实验时间:13:45 - 15:25
实验序号:实验5
实验名称:网络编程与安全
实验内容:
1、掌握Java Socket的相关内容;
2、学会建立客户端与服务器端之间的联系;
3、学习并应用密码学的相关内容
二、实验内容
提交点一
- 结对实现中缀表达式转后缀表达式的功能 MyBC.java
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.java
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;
}
}
实验截图
提交点二
- 结对编程:1人负责客户端,一人负责服务器
基于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;
/*5303 负责服务器*/
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;
/*5304 负责客户端*/
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("服务器已断开");
}
}
}
实验截图
提交点三
- 加密结对编程:1人负责客户端,一人负责服务器
客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加 密后通过网络把密文发送给服务器
服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果
运行截图
提交点四
实验截图
客户端
服务器
提交点五
实验截图
客户端
服务器