• 20155215 宣言 实验五 网络编程与安全 实验报告


    实验要求

    1.没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程;

    2.完成实验、撰写实验报告,实验报告模板见QQ群,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等);

    3.实验报告中统计自己的PSP(Personal Software Process)时间:

    步骤 耗时 百分比
    需求分析
    设计
    代码实现
    测试
    分析总结

    实验内容

    一、两人一组结对编程:

    1. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
    2. 结对实现中缀表达式转后缀表达式的功能 MyBC.java
    3. 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
    4. 上传测试代码运行结果截图和码云链接

    这题一共有三个代码,比起后面的四道题,这题还是较为简单的。
    MyBC.java的代码如下所示:

    /**
     * Created by XY on 2017/6/1.
     */
    
    import java.util.Iterator;
    import java.util.LinkedList;
    
    public class MyBC {
        private static LinkedList<String> op1 = new LinkedList<>();
        private static LinkedList<String> op2 = new LinkedList<>();
        private static StringBuilder a = new StringBuilder();
    
        public StringBuilder houzhui(LinkedList<String> list) {
            Iterator<String> i = list.iterator();
            while (i.hasNext()) {
                String s = i.next();
                if (isOperator(s)) {
                    if (op1.isEmpty()) {
                        op1.push(s);
                    } else {
                        if (priority(op1.peek()) <= priority(s) && !s.equals(")")) {
                            op1.push(s);
                        } else if (!s.equals(")") && priority(op1.peek()) > priority(s)) {
                            while (op1.size() != 0 && priority(op1.peek()) >= priority(s)
                                    && !op1.peek().equals("(")) {
                                if (!op1.peek().equals("(")) {
                                    String operator = op1.pop();
                                    a.append(operator).append(" ");
                                    op2.push(operator);
                                }
                            }
                            op1.push(s);
                        } else if (s.equals(")")) {
                            while (!op1.peek().equals("(")) {
                                String operator = op1.pop();
                                a.append(operator).append(" ");
                                op2.push(operator);
                            }
                            op1.pop();
                        }
                    }
                } else {
                    a.append(s).append(" ");
                    op2.push(s);
                }
            }
            if (!op1.isEmpty()) {
                Iterator<String> iterator = op1.iterator();
                while (iterator.hasNext()) {
                    String operator = iterator.next();
                    a.append(operator).append(" ");
                    op2.push(operator);
                    iterator.remove();
                }
            }
            return a;
        }
    
        private static boolean isOperator(String oper) {
            if (oper.equals("+") || oper.equals("-") || oper.equals("/") || oper.equals("*")
                    || oper.equals("(") || oper.equals(")")) {
                return true;
            }
            return false;
        }
    
        private static int priority(String s) {
            switch (s) {
                case "+":
                    return 1;
                case "-":
                    return 1;
                case "*":
                    return 2;
                case "/":
                    return 2;
                case "(":
                    return 3;
                case ")":
                    return 3;
                default:
                    return 0;
            }
        }
    }
    
    
    

    MyBCTest.java的代码如下:

    /**
     * Created by XY on 2017/6/1.
     */
    
    import java.util.Iterator;
    import java.util.LinkedList;
    
    public class MyBC {
        private static LinkedList<String> op1 = new LinkedList<>();
        private static LinkedList<String> op2 = new LinkedList<>();
        private static StringBuilder a = new StringBuilder();
    
        public StringBuilder houzhui(LinkedList<String> list) {
            Iterator<String> i = list.iterator();
            while (i.hasNext()) {
                String s = i.next();
                if (isOperator(s)) {
                    if (op1.isEmpty()) {
                        op1.push(s);
                    } else {
                        if (priority(op1.peek()) <= priority(s) && !s.equals(")")) {
                            op1.push(s);
                        } else if (!s.equals(")") && priority(op1.peek()) > priority(s)) {
                            while (op1.size() != 0 && priority(op1.peek()) >= priority(s)
                                    && !op1.peek().equals("(")) {
                                if (!op1.peek().equals("(")) {
                                    String operator = op1.pop();
                                    a.append(operator).append(" ");
                                    op2.push(operator);
                                }
                            }
                            op1.push(s);
                        } else if (s.equals(")")) {
                            while (!op1.peek().equals("(")) {
                                String operator = op1.pop();
                                a.append(operator).append(" ");
                                op2.push(operator);
                            }
                            op1.pop();
                        }
                    }
                } else {
                    a.append(s).append(" ");
                    op2.push(s);
                }
            }
            if (!op1.isEmpty()) {
                Iterator<String> iterator = op1.iterator();
                while (iterator.hasNext()) {
                    String operator = iterator.next();
                    a.append(operator).append(" ");
                    op2.push(operator);
                    iterator.remove();
                }
            }
            return a;
        }
    
        private static boolean isOperator(String oper) {
            if (oper.equals("+") || oper.equals("-") || oper.equals("/") || oper.equals("*")
                    || oper.equals("(") || oper.equals(")")) {
                return true;
            }
            return false;
        }
    
        private static int priority(String s) {
            switch (s) {
                case "+":
                    return 1;
                case "-":
                    return 1;
                case "*":
                    return 2;
                case "/":
                    return 2;
                case "(":
                    return 3;
                case ")":
                    return 3;
                default:
                    return 0;
            }
        }
    }
    
    
    

    MyDC的代码如下:

    /**
     * Created by XY on 2017/6/1.
     */
    
    import java.util.LinkedList;
    
    
    
    public class MyDC {
        public static int evaluate(StringBuilder b) {
            LinkedList<String> mList = new LinkedList<>();
            String[] postStr = b.toString().split(" ");
            int result;
            for (String s : postStr) {
                if (fuhao(s)) {
                    if (!mList.isEmpty()) {
                        int num1 = Integer.valueOf(mList.pop());
                        int num2 = Integer.valueOf(mList.pop());
                        if (s.equals("/") && num1 == 0) {
                            System.out.println("除数不能为0");
                            return 0;
                        }
                        int newNum = cal(num2, num1, s);
                        mList.push(String.valueOf(newNum));
                    }
                } else {
                    mList.push(s);
                }
            }
            //if (!mList.isEmpty()) {
            //System.out.println("result: "+mList.pop());
          result=Integer.parseInt(mList.pop());
            // }
    
    
            return result;
        }
    
        private static boolean fuhao(String a) {
            if (a.equals("+") || a.equals("-") || a.equals("/") || a.equals("*")
                    || a.equals("(") || a.equals(")")) {
                return true;
            }
            return false;
        }
        /*private static int priority(String s) {
    
            switch (s) {
                case "+":
                   return 1;
                case "-":
                  return 1;
             case "*":
    
                    return 2;
    
                case "/":
    
                    return 2;
    
                case "(":
                  return 3;
               case ")":
                 return 3;
                default:
                  return 0;
    
            }
        }*/
    
        private static int cal(int num1, int num2, String operator) {
            switch (operator) {
                case "+":
                    return num1 + num2;
                case "-":
                    return num1 - num2;
                case "*":
                    return num1 * num2;
                case "/":
                    return num1 / num2;
                default:
                    return 0;
            }
        }
    }
    
        /*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人负责客户端,一人负责服务器

    1. 注意责任归宿,要会通过测试证明自己没有问题
    2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
    4. 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    5. 客户端显示服务器发送过来的结果
    6. 上传测试结果截图和码云链接

    服务器的代码如下:

    /**
     * Created by XY on 2017/6/2.
     */
    import java.io.*;
    import java.net.*;
    
    import static java.lang.Integer.*;
    
    public class fuwuqi {
        public static void main(String[] args) {
            ServerSocket serverSocket = null;
            Socket socket = null;
            OutputStream os = null;
            InputStream is = null;
            //监听端口号
            int port = 10000;
            try {
                //建立连接
                serverSocket = new ServerSocket(port);
                System.out.println("建立连接成功!");
                //获得连接
                socket = serverSocket.accept();
                System.out.println("获得连接成功!");
                //接收客户端发送内容
                is = socket.getInputStream();
                byte[] b = new byte[1024];
                int n = is.read(b);
                System.out.println("接收数据成功!");
                //输出
                String message=new String(b,0,n);
                System.out.println("来自客户端的数据内容为:" + message);
                String result=code06011.dealEquation(message);
                //向客户端发送反馈内容
                //os = socket.getOutputStream();
                //os.write(b,0,n);
                os = socket.getOutputStream();
                os.write(result.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                try{
                    //关闭流和连接
                    os.close();
                    is.close();
                    socket.close();
                    serverSocket.close();
                }catch(Exception e){}
            }
        }
    }
    
    
    

    客户端的代码如下

    /**
     * Created by XY on 2017/6/2.
     */
    import java.io.*;
    import java.net.*;
    public class kehuduan {
        public static void main(String[] args) {
            Socket socket = null;
            InputStream is = null;
            OutputStream os = null;
            //服务器端IP地址
            String serverIP = "10.43.32.95";
            //服务器端端口号
            int port = 10000;
            //发送内容
            System.out.println("输入中缀表达式:(1+2)*3/4");
            String data = code06011.toSuffix("(1+2)*3/4");
            System.out.println("转换后缀表达式:"+data);
    
            try {
                //建立连接
                socket = new Socket(serverIP, port);
                System.out.println("建立连接成功!");
                //发送数据
                os = socket.getOutputStream();
                os.write(data.getBytes());
                System.out.println("发送数据成功!");
                //接收数据
                is = socket.getInputStream();
                byte[] b = new byte[1024];
                int n = is.read(b);
                System.out.println("接收数据成功!");
                //输出反馈数据
                System.out.println("来自服务器的数据内容为:" + new String(b, 0, n));
            } catch (Exception e) {
                e.printStackTrace(); //打印异常信息
            } finally {
                try {
                    //关闭流和连接
                    is.close();
                    os.close();
                    socket.close();
                } catch (Exception e2) {
                }
            }
        }
    }
    
    

    三、加密结对编程:1人负责客户端,一人负责服务器

    1. 注意责任归宿,要会通过测试证明自己没有问题
    2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
    4. 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    5. 客户端显示服务器发送过来的结果
    6. 上传测试结果截图和码云链接

    这题一共有三个代码
    ComputeTCPServer代码如下:

    /**
     * Created by XY on 2017/6/1.
     */
    import java.net.*;
    import java.io.*;
    import java.security.*;
    import java.security.spec.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    import javax.crypto.interfaces.*;
    import java.security.interfaces.*;
    import java.math.*;
    public class ComputeTCPServer{
        public static void main(String srgs[]) throws Exception
        {
            ServerSocket sc = null;
            Socket socket=null;
            try
            {
                sc= new ServerSocket(9999);//创建服务器套接字
                System.out.println("端口号:" + sc.getLocalPort());
                System.out.println("服务器已经启动...");
                socket = sc.accept();   //等待客户端连接
                System.out.println("已经建立连接");//获得网络输入流对象的引用
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获得网络输出流对象的引用
                PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
    
                //使用服务器端RSA的私钥对DES的密钥进行解密
                String aline2=in.readLine();
                BigInteger c=new BigInteger(aline2);
                FileInputStream f=new FileInputStream("Skey_RSA_priv.dat");
                ObjectInputStream b=new ObjectInputStream(f);
                RSAPrivateKey prk=(RSAPrivateKey)b.readObject( );
    
                BigInteger d=prk.getPrivateExponent();
                BigInteger n=prk.getModulus();
                BigInteger m=c.modPow(d,n);
                byte[] keykb=m.toByteArray();
    
                //使用DES对密文进行解密
                String aline=in.readLine();//读取客户端传送来的数据
                byte[] ctext=parseHexStr2Byte(aline);
                Key k=new  SecretKeySpec(keykb,"DESede");
                Cipher cp=Cipher.getInstance("DESede");
                cp.init(Cipher.DECRYPT_MODE, k);
                byte []ptext=cp.doFinal(ctext);
                String p=new String(ptext,"UTF8");
                System.out.println("从客户端接收到信息为:"+p); //通过网络输出流返回结果给客户端
    
                //验证明文的准确性
                String aline3=in.readLine();
                String x=p;
                MessageDigest m2=MessageDigest.getInstance("MD5");
                m2.update(x.getBytes( ));
                byte a[ ]=m2.digest( );
                String result="";
                for (int i=0; i<a.length; i++)
                {
                    result+=Integer.toHexString((0x000000ff & a[i]) |
                            0xffffff00).substring(6);
                }
                System.out.println(result);
    
                if(aline3.equals(result))
                {
                    System.out.println("匹配成功");
                }
    
                out.println("匹配成功");
                out.close();
                in.close();
                sc.close();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        public static byte[] parseHexStr2Byte(String hexStr)
        {
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length()/2];
            for (int i = 0;i< hexStr.length()/2; i++)
            {
                int high = Integer.parseInt(hexStr.substring(i*2, i*2+1 ), 16);
                int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
        public static String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++)
            {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1)
                {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
    }
    
    

    SocketService的代码如下:

    /**
     * Created by XY on 2017/6/1.
     */
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class SocketService {
        //搭建服务器端
        public static void main(String[] args) throws IOException{
            SocketService socketService = new SocketService();
            //1、a)创建一个服务器端Socket,即SocketService
            socketService.oneServer();
        }
        public  void oneServer(){
            try{
                ServerSocket server=null;
                try{
                    server=new ServerSocket(9999);
                    //b)指定绑定的端口,并监听此端口。
                    System.out.println("服务器启动成功");
                    //创建一个ServerSocket在端口5200监听客户请求
                }catch(Exception e) {
                    System.out.println("没有启动监听:"+e);
                    //出错,打印出错信息
                }
                Socket socket=null;
                try{
                    socket=server.accept();
                    //2、调用accept()方法开始监听,等待客户端的连接
                    //使用accept()阻塞等待客户请求,有客户
                    //请求到来则产生一个Socket对象,并继续执行
                }catch(Exception e) {
                    System.out.println("Error."+e);
                    //出错,打印出错信息
                }
                //3、获取输入流,并读取客户端信息
                String line;
                BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                //由Socket对象得到输入流,并构造相应的BufferedReader对象
                PrintWriter writer=new PrintWriter(socket.getOutputStream());
                //由Socket对象得到输出流,并构造PrintWriter对象
                BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
                //由系统标准输入设备构造BufferedReader对象
                System.out.println("Client:"+in.readLine());
                //在标准输出上打印从客户端读入的字符串
                line=br.readLine();
                //从标准输入读入一字符串
                //4、获取输出流,响应客户端的请求
                while(!line.equals("end")){
                    //如果该字符串为"end",则停止循环
                    writer.println(line);
                    //向客户端输出该字符串
                    writer.flush();
                    //刷新输出流,使Client马上收到该字符串
                    System.out.println("Server:"+line);
                    //在系统标准输出上打印读入的字符串
                    System.out.println("Client:"+in.readLine());
                    //从Client读入一字符串,并打印到标准输出上
                    line=br.readLine();
                    //从系统标准输入读入一字符串
                } //继续循环
    
                //5、关闭资源
                writer.close(); //关闭Socket输出流
                in.close(); //关闭Socket输入流
                socket.close(); //关闭Socket
                server.close(); //关闭ServerSocket
            }catch(Exception e) {//出错,打印出错信息
                System.out.println("Error."+e);
            }
        }
    }
    
    

    StockCline的代码如下:

    /**
     * Created by XY on 2017/6/1.
     */
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.URL;
    
    public class StockCline{
        // 搭建客户端
        public static void main(String[] args) throws IOException {
            try {
                // 1、创建客户端Socket,指定服务器地址和端口
                // Socket socket=new Socket("127.0.0.1",5200);
                Socket socket = new Socket("127.0.0.1", 9999);
                System.out.println("客户端启动成功");
                // 2、获取输出流,向服务器端发送信息
                // 向本机的52000端口发出客户请求
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                // 由系统标准输入设备构造BufferedReader对象
                PrintWriter write = new PrintWriter(socket.getOutputStream());
                // 由Socket对象得到输出流,并构造PrintWriter对象
                //3、获取输入流,并读取服务器端的响应信息
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 由Socket对象得到输入流,并构造相应的BufferedReader对象
                String readline;
                readline = br.readLine(); // 从系统标准输入读入一字符串
                while (!readline.equals("end")) {
                    // 若从标准输入读入的字符串为 "end"则停止循环
                    write.println(readline);
                    // 将从系统标准输入读入的字符串输出到Server
                    write.flush();
                    // 刷新输出流,使Server马上收到该字符串
                    System.out.println("Client:" + readline);
                    // 在系统标准输出上打印读入的字符串
                    System.out.println("Server:" + in.readLine());
                    // 从Server读入一字符串,并打印到标准输出上
                    readline = br.readLine(); // 从系统标准输入读入一字符串
                } // 继续循环
                //4、关闭资源
                write.close(); // 关闭Socket输出流
                in.close(); // 关闭Socket输入流
                socket.close(); // 关闭Socket
            } catch (Exception e) {
                System.out.println("can not listen to:" + e);// 出错,打印出错信息
            }
        }
    
    }
    
    

    四、密钥分发结对编程:1人负责客户端,一人负责服务器

    1. 注意责任归宿,要会通过测试证明自己没有问题
    2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
    4. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    5. 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    6. 客户端显示服务器发送过来的结果
    7. 上传测试结果截图和码云链接

    五、完整性校验结对编程:1人负责客户端,一人负责服务器

    1. 注意责任归宿,要会通过测试证明自己没有问题
    2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    4. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    5. 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    6. 客户端显示服务器发送过来的结果
    7. 上传测试结果截图和码云链接
      最后两题其实和第三题类似,但是有一些小的改动,所以代码我就不重复贴了,下面是我的运行截图:

    实验感想

    这次实验我觉得难度真的很大,我和我的结对对象20155232花了整整一周来做这个实验。我们在网上查了很多资料,然后请教同学,最后才赶在最后期限做完的,感觉自己不会的还有很多,还需要加油。

    PSP时间

    步骤 耗时 百分比
    需求分析 30 7.5%
    设计 50 12.5%
    代码实现 240 60%
    测试 60 15%
    分析总结 20 5%
  • 相关阅读:
    tomcat做成windows服务之后使用JMX监控的问题
    Spring CORS
    人大金仓
    今天遇到奇怪的事:SVN本地代码的标记突然没了,Clean up也报错
    你真得懂Javascript中的==等于运算符吗?
    Codeforces 384E 线段树+dfs序
    一个图形引擎的画面风格是由那些因素(技术)决定的?
    【BZOJ 1146】【CTSC 2008】网络管理network
    ajax核心技术1---XMLHttpRequset对象的使用
    Android中Application类的详解:
  • 原文地址:https://www.cnblogs.com/xuanyan/p/6937205.html
Copyright © 2020-2023  润新知