zoukankan      html  css  js  c++  java
  • 20192317邓子彦 实验四 《数据结构与面向对象程序设计》实验报告

    20192317邓子彦 实验四 《数据结构与面向对象程序设计》实验报告


    学号 2019-2020 《数据结构与面向对象程序设计》实验四报告
    课程:《程序设计与数据结构》
    班级: 1923
    姓名: 邓子彦
    学号:20192317
    实验教师:王志强
    实验日期:2020年10月22日
    必修/选修: 必修

    • 1.实验内容

    (一)Java Socket编程

    1.学习蓝墨云上教材《Java和Android编程》“第16章 输入/输出 ”和“第22章 网络”,学习JavaSocket编程
    2.结对编程。结对伙伴A编写客户端SocketClient.java,结对伙伴B编写服务器端。
    3.截图加学号水印上传蓝墨云,代码push到码云,并撰写实验报告。

    (二)Java和密码学

    参考 http://www.cnblogs.com/rocedu/p/6683948.html

    以结对的方式完成Java密码学相关内容的学习(帖子中所有代码和相关知识点需要学习)。提交学习成果码云链接和代表性成果截图,要有学号水印。

    (三)编写有理数/复数计算器

    结对编程,结对伙伴A编写有理数计算器。结对伙伴B编写复数计算器。截图加水印上传蓝墨云,代码push码云。

    (四)远程有理数计算器

    结对编程,结对伙伴A编程实现客户端,结果伙伴B实现服务器端。
    客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴B(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端A,A收到结果后输出结果。截图加水印上传蓝墨云,代码push码云。

    (五)远程复数计算器

    结对编程,结对伙伴B编程实现客户端,结果伙伴A实现服务器端。
    客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴A(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端B,B收到结果后输出结果。截图加水印上传蓝墨云,代码push码云。

    • 2.实验结果

    (一)Java Socket编程

    • 1.一个人实现了客户端和服务器
    • 实验代码
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class server {
        public static void main(String[] args) throws Exception {
            // 监听指定的端口
            int port = 10086;
            ServerSocket server = new ServerSocket(port);
    
            // server将一直等待连接的到来
            System.out.println("server将一直等待连接的到来");
            Socket socket = server.accept();
            // 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int len;
            StringBuilder sb = new StringBuilder();
            //只有当客户端关闭它的输出流的时候,服务端才能取得结尾的-1
            while ((len = inputStream.read(bytes)) != -1) {
                // 注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
                sb.append(new String(bytes, 0, len, "UTF-8"));
            }
            System.out.println("get message from client: " + sb);
    
            inputStream.close();
            outputStream.close();
            socket.close();
            server.close();
        }
    }
    
    • 2
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class client {
        public static void main(String args[]) throws Exception {
            // 要连接的服务端IP地址和端口
            String host = "192.168.248.1";
            int port = 10086;
            // 与服务端建立连接
            Socket socket = new Socket(host, port);
            // 建立连接后获得输出流
            OutputStream outputStream = socket.getOutputStream();
            String message = "欢迎来到地狱的入口!";
            socket.getOutputStream().write(message.getBytes("UTF-8"));
            //通过shutdownOutput高速服务器已经发送完数据,后续只能接受数据
            socket.shutdownOutput();
    
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int len;
            StringBuilder sb = new StringBuilder();
            while ((len = inputStream.read(bytes)) != -1) {
                //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
                sb.append(new String(bytes, 0, len,"UTF-8"));
            }
            System.out.println("get message from server: " + sb);
    
            inputStream.close();
            outputStream.close();
            socket.close();
        }
    }
    
    • 2.实验截图

    • (二)Java和密码学

    • 实验代码

    • CasesarCode

    package cryptology;
    
    import java.io.BufferedReader;
    
    import java.io.InputStreamReader;
    
    import java.util.Scanner;
    
    
    public class CaesarCode {
    
        char ciphertext[]; // 密文
    
        int key;
    
        char plaintext[]; // 明文
    
        StringBuffer plaintextStr = new StringBuffer("");
    
        StringBuffer ciphertextStr = new StringBuffer("");
    
        final int max = 500; // 最大字符
    
        public static void main(String[] args) {
            CaesarCode m = new CaesarCode();
            m.setKey();
            m.getPlaintext();
            m.encryption();
            m.deciphering();
            m.display();
        }
        /**
    
         * 设置密钥,返回偏移值
    
         * @return
    
         */
    
        int setKey() {
    
            System.out.println("请输入一个Caesar数字密钥:");
    
            while (true) {
    
                Scanner sc = new Scanner(System.in);
    
                try {
    
                    key = sc.nextInt() % 26; // %26的意义是获取密钥的偏移值
    
                    return key;
    
                } catch (Exception e) {
    
                    System.out.println("ERROR__请重新输入整数密钥...");
    
                }
    
            }
    
        }
    
        /**
    
         * 获得明文
    
         */
    
        void getPlaintext() {
    
            plaintext = new char[max];
    
            for (int j = 0; j < max; j++) {
    
                plaintext[j] = '★'; // 设置临时变量将数组填充,因明文中可存在' '空,所以需要填充判断
    
            }
    
            int i = 0;
    
            char ch = ' ';
    
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
    
            System.out.println("请输入明文");
    
            try {
    
                ch = (char) bf.read(); // 获得字符
    
                while (ch != '
    ' && ch != '
    ') { // 回车
    
                    plaintext[i] = ch;
    
                    i++;
    
                    try {
    
                        ch = (char) bf.read();
    
                    } catch (Exception e) {
    
                        e.printStackTrace();
    
                    }
    
                }
    
            } catch (Exception e) {
    
                e.printStackTrace();
    
            }
    
        }
    
        /**
    
         * 加密
    
         */
    
        void encryption() {
    
            ciphertext = new char[max];
    
            for (int j = 0; j < max; j++) {
    
                ciphertext[j] = '★'; // 设置临时变量将数组填充,因明文中可存在' '空,所以需要填充判断
    
            }
    
            for (int i = 0; i < plaintext.length; i++) {
    
                if (plaintext[i] != '★') {
    
                    int temp = plaintext[i] + key;	// 偏移后的ASCII码
    
                    ciphertext[i]=(char)temp; // 加密符号
    
                    ciphertextStr.append(ciphertext[i]); // 拼接字符串
    
                } else {
    
                    break;
    
                }
    
            }
    
        }
    
        /**
    
         * 解密
    
         */
    
        void deciphering() {
    
            char c = ' ';
    
            for (int i = 0; i < ciphertext.length; i++) {
    
                if (ciphertext[i] != '★') {
    
                    int temp = ciphertext[i] - key;
    
                    c = (char) temp;
    
                    plaintextStr.append(c);		// 拼接解密字符串
    
                } else {
    
                    break;
    
                }
    
            }
    
        }
    
        /**
    
         * 显示对比结果
    
         */
    
        void display() {
    
            System.out.println("密文明文对比");
    
            System.out.println("密文:" + ciphertextStr);
    
            System.out.println("明文:" + plaintextStr);
    
        }
    
    • 实验截图

    • DES

    package com.journaldev.des;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.spec.AlgorithmParameterSpec;
    
    import javax.crypto.Cipher;
    import javax.crypto.CipherInputStream;
    import javax.crypto.CipherOutputStream;
    import javax.crypto.KeyGenerator;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    
    public class DES {
        private static Cipher encryptCipher;
        private static Cipher decryptCipher;
        private static final byte[] iv = { 11, 22, 33, 44, 99, 88, 77, 66 };
    
        public static void main(String[] args) {
            String clearTextFile = "D:\CaesarCode\src\com\journaldev\des\DES1.txt";
            String cipherTextFile = "D:\CaesarCode\src\com\journaldev\des\DES2.txt";
            String clearTextNewFile = "D:\CaesarCode\src\com\journaldev\des\DES3.txt";
    
            try {
                // create SecretKey using KeyGenerator
                SecretKey key = KeyGenerator.getInstance("DES").generateKey();
                AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    
                // get Cipher instance and initiate in encrypt mode
                encryptCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
                encryptCipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
    
                // get Cipher instance and initiate in decrypt mode
                decryptCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
                decryptCipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
    
                // method to encrypt clear text file to encrypted file
                encrypt(new FileInputStream(clearTextFile), new FileOutputStream(cipherTextFile));
    
                // method to decrypt encrypted file to clear text file
                decrypt(new FileInputStream(cipherTextFile), new FileOutputStream(clearTextNewFile));
                System.out.println("DONE");
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
                    | InvalidAlgorithmParameterException | IOException e) {
                e.printStackTrace();
            }
    
        }
    
        private static void encrypt(InputStream is, OutputStream os) throws IOException {
    
            // create CipherOutputStream to encrypt the data using encryptCipher
            os = new CipherOutputStream(os, encryptCipher);
            writeData(is, os);
        }
    
        private static void decrypt(InputStream is, OutputStream os) throws IOException {
    
            // create CipherOutputStream to decrypt the data using decryptCipher
            is = new CipherInputStream(is, decryptCipher);
            writeData(is, os);
        }
    
        // utility method to read data from input stream and write to output stream
        private static void writeData(InputStream is, OutputStream os) throws IOException {
            byte[] buf = new byte[1024];
            int numRead = 0;
            // read and write operation
            while ((numRead = is.read(buf)) >= 0) {
                os.write(buf, 0, numRead);
            }
            os.close();
            is.close();
        }
    
    }
    
    • 实验截图

    • (三)编写有理数/复数计算器

    • 有理数计算器

    • 实验代码

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class youlishu{
        public static void main(String[] args) throws NumberFormatException, IOException{
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
            String[] strs=br.readLine().split(" ");
            br.close();
            numAdd(strs[0],strs[1]);
         //   numSub(strs[0],strs[1]);
         //   numMult(strs[0],strs[1]);
         //   numDivi(strs[0],strs[1]);
        }
        //  化简分数形式有理数
        public static String numSimply(String str) {
            String[] strs=str.split("/");
            Long str1=Long.parseLong(strs[0]);//分子
            Long str2=Long.parseLong(strs[1]);//分母
            if(str2<0) {
                str2=-str2;
                str1=-str1;
            }
            Long num1=str1/str2;
            Long num2=str1%str2;
            if(num2<0) {
                num2=-num2;
            }
    //	  真分数
            if(num1==0&&num2!=0) {
                Long gcd=getGCD(str1,str2);
                str=str1/gcd+"/"+str2/gcd;
    //		  判断str1是正数还是负数
                if(str1>0) {
                    return str;
                }else {
                    return "("+str+")";
                }
            }
    //	  整数
            else if(num2==0&&num1!=0) {
                String result=String.valueOf(num1);
    //		  判断str1是正数还是负数
                if(str1>0) {
                    return result;
                }else {
                    return "("+result+")";
                }
            }
    //	  为0
            else if(num1==0&&num2==0) {
                return "0";
            }
    //	  假分数
            else {
    //		  对假分数的真分数部分化简
                String result1=num2+"/"+str2;
                String result2=numSimply(result1);
    //		  判断num1是正数还是负数
                if(num1>0) {
                    return num1+" "+result2;
                }else {
                    return "("+num1+" "+result2+")";
                }
            }
        }
        //  利用辗转相除法求两个数的最大公约数
    //  这个方法默认a<b,因为用于真分数的化简,分子一定小于分母
        public static Long getGCD(Long a,Long b) {
            while(b%a!=0) {
                Long temp=b%a;
                b=a;
                a=temp;
            }
    //	  如果最大公约数是负数,需要把它转换为正数
            if(a<0) {
                a=-a;
            }
            return a;
        }
        //  有理数加法
        public static void numAdd(String str1,String str2) {
            String[] strs1=str1.split("/");
            String[] strs2=str2.split("/");
            Long son1=Long.parseLong(strs1[0]);
            Long mon1=Long.parseLong(strs1[1]);
            Long son2=Long.parseLong(strs2[0]);
            Long mon2=Long.parseLong(strs2[1]);
            Long son3=son1*mon2+son2*mon1;
            Long mon3=mon1*mon2;
            String str3=son3+"/"+mon3;
            String result1=numSimply(str1);
            String result2=numSimply(str2);
            String result3=numSimply(str3);
            System.out.println(result1+" + "+result2+" = "+result3);
        }
        //  有理数减法
        public static void numSub(String str1,String str2) {
            String[] strs1=str1.split("/");
            String[] strs2=str2.split("/");
            Long son1=Long.parseLong(strs1[0]);
            Long mon1=Long.parseLong(strs1[1]);
            Long son2=Long.parseLong(strs2[0]);
            Long mon2=Long.parseLong(strs2[1]);
            Long son3=son1*mon2-son2*mon1;
            Long mon3=mon1*mon2;
            String str3=son3+"/"+mon3;
            String result1=numSimply(str1);
            String result2=numSimply(str2);
            String result3=numSimply(str3);
            System.out.println(result1+" - "+result2+" = "+result3);
        }
        //  有理数乘法
        public static void numMult(String str1,String str2) {
            String[] strs1=str1.split("/");
            String[] strs2=str2.split("/");
            Long son1=Long.parseLong(strs1[0]);
            Long mon1=Long.parseLong(strs1[1]);
            Long son2=Long.parseLong(strs2[0]);
            Long mon2=Long.parseLong(strs2[1]);
            Long son3=son1*son2;
            Long mon3=mon1*mon2;
            String str3=son3+"/"+mon3;
            String result1=numSimply(str1);
            String result2=numSimply(str2);
            String result3=numSimply(str3);
            System.out.println(result1+" * "+result2+" = "+result3);
        }
        //  有理数除法
        public static void numDivi(String str1,String str2) {
            String[] strs1=str1.split("/");
            String[] strs2=str2.split("/");
            Long son1=Long.parseLong(strs1[0]);
            Long mon1=Long.parseLong(strs1[1]);
            Long son2=Long.parseLong(strs2[0]);
            Long mon2=Long.parseLong(strs2[1]);
            String result1=numSimply(str1);
            String result2=numSimply(str2);
            if(result2.equals("0")) {
                System.out.print(result1+" / "+result2+" = Inf");
            }else {
                Long son3=son1*mon2;
                Long mon3=mon1*son2;
                String str3=son3+"/"+mon3;
                String result3=numSimply(str3);
                System.out.print(result1+" / "+result2+" = "+result3);
            }
        }
    }
    
    • 实验截图

    • (四)远程有理数计算器

    • (五)远程复数计算器

    • 实验截图




    • 3.实验过程中遇到的问题及解决过程

    问题1:刚开始按照教程走的时候,客户端和服务器不能连接,显示不出消息

    解决:上CSDN查找教程,查怎么样实现客户端和服务器连接。得到的答案是要找到客户端的,需要在命令行中输入ipconfig找到自己电脑的ip地址,然后统一一个不被占用的端口(我选的是10086)

    问题2:远程计算器不懂该怎么连接

    解决:上CSDN找了很多教程,又询问了其他已经完成的同学,最后在大家帮助下完成了远程计算器的连接。

    • 4.其他(感悟、思考等)

    实验越来越难做,这次我选择独狼一人做完两个任务,导致工作量和需要学习的内容很多,一整周都在忙Java的学习,不过也让我感到充实,也提醒自己不能轻易地被困难击败。

    • 5.参考资料

    《Java程序设计与数据结构教程(第二版)》

    《Java程序设计与数据结构教程(第二版)》学习指导

  • 相关阅读:
    ubuntu下文件安装与卸载
    webkit中的JavaScriptCore部分
    ubuntu 显示文件夹中的隐藏文件
    C语言中的fscanf函数
    test
    Use SandCastle to generate help document automatically.
    XElement Getting OuterXML and InnerXML
    XUACompatible meta 用法
    Adobe Dreamweaver CS5.5 中文版 下载 注册码
    The Difference Between jQuery’s .bind(), .live(), and .delegate()
  • 原文地址:https://www.cnblogs.com/dengziyan/p/13908822.html
Copyright © 2011-2022 走看看