zoukankan      html  css  js  c++  java
  • 实验五网络编程

    实验五网络编程

    课程:Java程序设计

    班级:1652

    姓名:孔月

    学号:20165208

    指导教师:娄嘉鹏

    实验日期:2018.5.28

    实验名称:网络编程

    实验内容、步骤与体会

    目录:

    (一) 结对实现中缀表达式转后缀表达式的功能 MyBC.java, 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
    import java.util.StringTokenizer;
    import java.util.Stack;
    
    public class MyDC {
        private final char ADD = '+';
        private final char SUBTRACT = '-';
        private final char MULTIPLY = '*';
        private final char DIVIDE = '/';
        private Stack<Integer> stack;
    
        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;
        }
    }
    
    
    import java.io.IOException;
    import java.util.Scanner;
    public class MyBC {
        private Stack theStack;
        private String input;
        private String output = "";
        public MyBC(String in) {
            input = in;
            int stackSize = input.length();
            theStack = new Stack(stackSize);
        }
        public String doTrans() {
            for (int j = 0; j < input.length(); j++) {
                char ch = input.charAt(j);
                switch (ch) {
                    case '+':
                    case '-':
                        gotOper(ch, 1);
                        break;
                    case '*':
                    case '/':
                        gotOper(ch, 2);
                        break;
                    case '(':
                        theStack.push(ch);
                        break;
                    case ')':
                        gotParen(ch);
                        break;
                    default:
                        output = output + ch;
                        break;
                }
            }
            while (!theStack.isEmpty()) {
                output = output + theStack.pop();
            }
            System.out.println(output);
            return output;
        }
        public void gotOper(char opThis, int prec1) {
            while (!theStack.isEmpty()) {
                char opTop = theStack.pop();
                if (opTop == '(') {
                    theStack.push(opTop);
                    break;
                }
                else {
                    int prec2;
                    if (opTop == '+' || opTop == '-')
                        prec2 = 1;
                    else
                        prec2 = 2;
                    if (prec2 < prec1) {
                        theStack.push(opTop);
                        break;
                    }
                    else
                        output = output + opTop;
                }
            }
            theStack.push(opThis);
        }
        public void gotParen(char ch){
            while (!theStack.isEmpty()) {
                char chx = theStack.pop();
                if (chx == '(')
                    break;
                else
                    output = output + chx;
            }
        }
        public static void main(String[] args) throws IOException {
            Scanner in = new Scanner(System.in);
            String input = in.nextLine();
            System.out.println(input);
            String output;
            MyBC theTrans = new MyBC(input);
            output = theTrans.doTrans();
        }
        class Stack {
            private int maxSize;
            private char[] stackArray;
            private int top;
            public Stack(int max) {
                maxSize = max;
                stackArray = new char[maxSize];
                top = -1;
            }
            public void push(char j) {
                stackArray[++top] = j;
            }
            public char pop() {
                return stackArray[top--];
            }
            public char peek() {
                return stackArray[top];
            }
            public boolean isEmpty() {
                return (top == -1);
            }
        }
    }
    

    实验效果如下图

    返回目录

    (二)结对编程:1人负责客户端,一人负责服务器 0. 注意责任归宿,要会通过测试证明自己没有问题 1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP 2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器 3. 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端 4. 客户端显示服务器发送过来的结果
    import java.io.*;
    import java.net.*;
    import static java.lang.Integer.*;
    
    public class Server {
        public static void main(String[] args) {
            ServerSocket serverSocket = null;
            Socket socket = null;
            OutputStream os = null;
            InputStream is = null;
            int port = 8087;
            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 output;
                MyBC theTrans = new MyBC(message);
                output = theTrans.doTrans();
                os = socket.getOutputStream();
                os.write(output.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                try{
                    os.close();
                    is.close();
                    socket.close();
                    serverSocket.close();
                }catch(Exception e){}
            }
        }
    }
    
    import java.io.*;
    import java.net.*;
    public class Client {
        public static void main(String[] args) {
            Socket socket = null;
            InputStream is = null;
            OutputStream os = null;
            String serverIP = "172.16.252.50";
            int port = 8087;
            System.out.println("输入中缀表达式:20-16/4+52-11*2");
            String output;
            MyBC theTrans = new MyBC("20-16/4+52-11*2");
            output = theTrans.doTrans();
            try {
                socket = new Socket(serverIP, port);
                System.out.println("建立连接成功!");
                os = socket.getOutputStream();
                os.write(output.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人负责客户端,一人负责服务器 0. 注意责任归宿,要会通过测试证明自己没有问题 1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP 2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器 3. 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端 4. 客户端显示服务器发送过来的结果
    import java.io.*;
    
    import java.net.Socket;
    
    public class ClientSend {
        public static void main(String[] args) {
            Socket s = null;
            try {
                s = new Socket("192.168.56.1", 12345);
            }catch (IOException e) {
                System.out.println("未连接到服务器");
            }
            try {
                DataInputStream input = new DataInputStream(s.getInputStream());
                System.out.print("请输入: 	");
                String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
                MyBC turner = new MyBC();
                String str1 = turner.turn(str);
                int length = 0, i = 0;
                while (str1.charAt(i) != '') {
                    length++;
                    i++;
                }
                String str2 = str1.substring(1, length - 1);
                SEnc senc = new SEnc(str2);//指定后缀表达式为明文字符
                senc.encrypt();//加密
            }catch(Exception e) {
                System.out.println("客户端异常:" + e.getMessage());
            }
            File sendfile = new File("SEnc.dat");
            File sendfile1 = new File("Keykb1.dat");
            FileInputStream fis = null;
            FileInputStream fis1 = null;
            byte[] buffer = new byte[4096 * 5];
            byte[] buffer1 = new byte[4096 * 5];
            OutputStream os;
            if(!sendfile.exists() || !sendfile1.exists()){
                System.out.println("客户端:要发送的文件不存在");
                return;
            }
            try {
                fis = new FileInputStream(sendfile);
                fis1 = new FileInputStream(sendfile1);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            }
            try {
                PrintStream ps = new PrintStream(s.getOutputStream());
                ps.println("111/#" + sendfile.getName() + "/#" + fis.available());
                ps.flush();
            } catch (IOException e) {
                System.out.println("服务器连接中断");
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            try {
                os = s.getOutputStream();
                int size = 0;
                while((size = fis.read(buffer)) != -1){
                    System.out.println("客户端发送数据包,大小为" + size);
                    os.write(buffer, 0, size);
                    os.flush();
                }
            } catch (FileNotFoundException e) {
                System.out.println("客户端读取文件出错");
            } catch (IOException e) {
                System.out.println("客户端输出文件出错");
            }finally{
                try {
                    if(fis != null)
                        fis.close();
                } catch (IOException e) {
                    System.out.println("客户端文件关闭出错");
                }
            }
            try {
                PrintStream ps1 = new PrintStream(s.getOutputStream());
                ps1.println("111/#" + sendfile1.getName() + "/#" + fis1.available());
                ps1.flush();
            } catch (IOException e) {
                System.out.println("服务器连接中断");
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            try {
                os = s.getOutputStream();
                int size = 0;
                while((size = fis1.read(buffer1)) != -1){
                    System.out.println("客户端发送数据包,大小为" + size);
                    os.write(buffer1, 0, size);
                    os.flush();
                }
            } catch (FileNotFoundException e) {
                System.out.println("客户端读取文件出错");
            } catch (IOException e) {
                System.out.println("客户端输出文件出错");
            }finally{
                try {
                    if(fis1 != null)
                        fis1.close();
                } catch (IOException e) {
                    System.out.println("客户端文件关闭出错");
                }
            }
            try{
                DataInputStream input = new DataInputStream(s.getInputStream());
                String ret = input.readUTF();
                System.out.println("服务器端返回过来的是: " + ret);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (s == null) {
                    try {
                        s.close();
                    } catch (IOException e) {
                        System.out.println("客户端 finally 异常:" + e.getMessage());
                    }
                }
            }
        }
    }
    

    最终运行效果如图

    (四)密钥分发结对编程:1人负责客户端,一人负责服务器
    1. 注意责任归宿,要会通过测试证明自己没有问题
    2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
    4. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    5. 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    6. 客户端显示服务器发送过来的结果
    7. 上传测试结果截图和码云链接
      测试代码
    import java.io.*;
    import java.math.*;
    import java.security.*;
    import java.security.spec.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    import javax.crypto.interfaces.*;
    
    public class Key_DH{
           //三个静态变量的定义从
    // C:j2sdk-1_4_0-docdocsguidesecurityjceJCERefGuide.html
    // 拷贝而来
    // The 1024 bit Diffie-Hellman modulus values used by SKIP
        private static final byte skip1024ModulusBytes[] = {
            (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58,
            (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD,
            (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4,
            (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B,
            (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D,
            (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C,
            (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C,
            (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6,
            (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0,
            (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B,
            (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB,
            (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D,
            (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD,
            (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43,
            (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C,
            (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C,
            (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C,
            (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40,
            (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C,
            (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72,
            (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03,
            (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29,
            (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C,
            (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB,
            (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B,
            (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08,
            (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D,
            (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C,
            (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22,
            (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB,
            (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55,
            (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7
        };
        // The SKIP 1024 bit modulus
        private static final BigInteger skip1024Modulus
                  = new BigInteger(1, skip1024ModulusBytes);
        // The base used with the SKIP 1024 bit modulus
        private static final BigInteger skip1024Base = BigInteger.valueOf(2);
    public static void main(String args[ ]) throws Exception{
        DHParameterSpec DHP=
    new DHParameterSpec(skip1024Modulus,skip1024Base);
    
         KeyPairGenerator kpg= KeyPairGenerator.getInstance("DH");
         kpg.initialize(DHP);
         KeyPair kp=kpg.genKeyPair();
    
         PublicKey pbk=kp.getPublic();
         PrivateKey prk=kp.getPrivate();
         // 保存公钥
         FileOutputStream  f1=new FileOutputStream(args[0]);
         ObjectOutputStream b1=new  ObjectOutputStream(f1);
         b1.writeObject(pbk);
         // 保存私钥
         FileOutputStream  f2=new FileOutputStream(args[1]);
         ObjectOutputStream b2=new  ObjectOutputStream(f2);
         b2.writeObject(prk);
       }      
    } 
    

    测试如下图

    (五)使用StarUML对实验中的代码进行建模

    完整性校验结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    3. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    4. 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    5. 客户端显示服务器发送过来的结果
    String x= exp;
        MessageDigest m=MessageDigest.getInstance("MD5");
        m.update(x.getBytes("UTF8"));
        byte s[ ]=m.digest( );
        String res="";
        for (int j=0; j<s.length; j++){
            res +=Integer.toHexString((0x000000ff & s[j]) |0xffffff00).substring(6);
        }
        System.out.printf("md5Check:" + md5.equals(res));
        
        ```
    

    String x= str2;
    MessageDigest m=MessageDigest.getInstance("MD5");
    m.update(x.getBytes("UTF8"));
    byte s[ ]=m.digest( );
    String result="";
    for (int j=0; j<s.length; j++){
    result+=Integer.toHexString((0x000000ff & s[j]) |0xffffff00).substring(6);
    }
    ```

    问题总结与体会

    • 问题1:有关客户端的问题刚开始完全没思路
    • 解决方案:重新看了一遍13章
    步骤 耗时 百分比
    需求分析 25 min 8.3%
    设计 70 min 23.3%
    代码实现 120 min 40%
    测试 40 min 13.3%
    分析总结 45 min 15%
  • 相关阅读:
    DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践
    UVA10071 Back to High School Physics
    UVA10071 Back to High School Physics
    UVA10055 Hashmat the Brave Warrior
    UVA10055 Hashmat the Brave Warrior
    UVA458 The Decoder
    UVA458 The Decoder
    HDU2054 A == B ?
    HDU2054 A == B ?
    POJ3414 Pots
  • 原文地址:https://www.cnblogs.com/KY-high/p/9131196.html
Copyright © 2011-2022 走看看