2018-2019-2 20175304 实验五《网络编程与安全》实验报告

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的功能计算后缀表达式的值,把结果发送给客户端

  • 客户端显示服务器发送过来的结果

运行截图

提交点四

实验截图
客户端

服务器

提交点五

实验截图
客户端

服务器

posted @ 2019-05-30 22:27  20175304刘朝尹  阅读(120)  评论(0编辑  收藏  举报