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

 课程:《程序设计与数据结构》
班级: 2023
姓名:王梦欣
学号:20202315
实验教师:王志强
实验日期:2021年9月30日
必修/选修: 必修

 
# # 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码云。

结对伙伴为20202304何锐

 

# # 2. 实验过程及结果

(一)Java Socket编程

客户端代码:

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/commit/91a932d83ac516d5e22a9cf3d75db586a9f92efe

 20202304何锐负责

import java.io.*;
import java.net.Socket;

public class SocketClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("172.16.230.134",2315);
        OutputStream outputStream = socket.getOutputStream();
        PrintWriter printWriter = new PrintWriter(outputStream);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
        String info1 = " 用户名:Herren,密码:20202304";
        String info = new String(info1.getBytes("GBK"),"GBK");
        outputStreamWriter.write(info1);
        outputStreamWriter.flush();
        socket.shutdownOutput();
        String reply = null;
        while (!((reply = bufferedReader.readLine()) ==null)){
            System.out.println("接收服务器的信息为:" + reply);
        }
        bufferedReader.close();
        inputStream.close();
        outputStreamWriter.close();
        printWriter.close();
        outputStream.close();
        socket.close();
    }
}

 

服务器端代码:

 20202315王梦欣负责

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket=new ServerSocket(2315);//新建服务器,端口:2315
        Socket socket=serverSocket.accept();//防止监听
        InputStream inputStream=socket.getInputStream();
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
        OutputStream outputStream=socket.getOutputStream();
        PrintWriter printWriter=new PrintWriter(outputStream);
        //读取用户输入
        String info=null;
        System.out.println("服务器已建立");
        while(!((info = bufferedReader.readLine()) ==null)){
            System.out.println("已读取,信息为:" + info);
        }
        String reply="I found you!";
        printWriter.write(reply);
        printWriter.flush();
        //关闭资源
        printWriter.close();
        outputStream.close();
        bufferedReader.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

 

运行结果:

 

 

 

 

 

(二)Java和密码学

Java和密码学部分有凯撒密码、Java对称加密-DES算法、Java非对称加密-RSA算法、使用密钥协定创建共享密钥、Java摘要算法-MD5等多项内容,参考娄老师的教程,学习成果如下

凯撒密码代码部分:

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/commit/b8fc22c2a2f7e4d76c1f344541f47794da7f1c6a

public class Password {
    public static void main(String args[]) throws Exception{
        String s=args[0];
        int key=Integer.parseInt(args[1]);
        String es="";
        for(int i=0;i<s.length();i++)
        {  char c=s.charAt(i);
            if(c>='a' && c<='z') // 是小写字母
            { c+=key%26;  //移动key%26位
                if(c<'a') c+=26;  //向左超界
                if(c>'z') c-=26;  //向右超界
            }
            else if(c>='A' && c<='Z') // 是大写字母
            {  c+=key%26;
                if(c<'A') c+=26;
                if(c>'Z') c-=26;
            }
            es+=c;
        }
        System.out.println(es);
    }
}

 

运行结果截图:

 

 java对称加密-DES算法代码部分:

码云代码:

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/master/Skey_DES.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/master/Skey_kb.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/master/SEnc.java

 

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/master/SDec.java

 

import java.io.*;
import javax.crypto.*;

public class Skey_DES {
    public static void main(String args[])
            throws Exception{
        KeyGenerator kg=KeyGenerator.getInstance("DESede");//获取密钥生成器
        kg.init(168);//初始化密钥生成器
        SecretKey k=kg.generateKey( );//生成密钥
        FileOutputStream  f=new FileOutputStream("key1.dat");
        ObjectOutputStream b=new  ObjectOutputStream(f);
        b.writeObject(k);//通过对象序列化方式将密钥保存在文件中
    }
}
import java.io.*;
import java.security.*;
public class Skey_kb {
    public static void main(String args[]) throws Exception{
        FileInputStream f=new FileInputStream("key1.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        Key k=(Key)b.readObject( );//获取密钥
        byte[ ] kb=k.getEncoded( );//获取主要编码格式
        FileOutputStream  f2=new FileOutputStream("keykb1.dat");
        f2.write(kb);//保存密钥编码格式
        // 打印密钥编码中的内容
        for(int i=0;i<kb.length;i++){
            System.out.print(kb[i]+",");
        }
    }
}
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.nio.charset.StandardCharsets;
import java.security.Key;

public class SEnc {
    public static void main(String[] args) throws Exception{
        String s ="hello world!";//获取等待加密的明文
        FileInputStream f =new FileInputStream("key1.dat");
        ObjectInputStream b =new ObjectInputStream(f);
        Key k = (Key)b.readObject();//从文件中获取密钥
        Cipher cp = Cipher.getInstance("DESede");//创建密码对象
        cp.init(Cipher.ENCRYPT_MODE,k);//初始化密码对象
        byte ptext[] = s.getBytes("UTF8");
        for(int i=0;i<ptext.length;i++){
            System.out.print(ptext[i]+",");
        }
        System.out.println("");
        byte ctext[]=cp.doFinal(ptext);//执行加密
        for(int i=0;i<ctext.length;i++){
            System.out.print(ctext[i] +",");
        }
        FileOutputStream f2 = new FileOutputStream("SEnc.dat");
        f2.write(ctext);//处理加密结果
    }
}
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class SDec {
    public static void main(String args[]) throws Exception{
        // 获取密文
        FileInputStream f=new FileInputStream("SEnc.dat");
        int num=f.available();
        byte[ ] ctext=new byte[num];
        f.read(ctext);
        // 获取密钥
        FileInputStream  f2=new FileInputStream("keykb1.dat");
        int num2=f2.available();
        byte[ ] keykb=new byte[num2];
        f2.read(keykb);
        SecretKeySpec 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);
    }
}

运行结果截图:(在DES算法运行成功后稍加修改尝试了AES算法)

 

 

 

 

 

 Java非对称加密-RSA算法代码部分

码云代码:https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Skey_RSA.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Enc_RSA.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Dec_RSA.java

import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Skey_RSA {
    public static void main(String args[]) throws Exception{
        //创建密钥对生成器
        KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
        //初始化密钥生成器
        kpg.initialize(1024);
        //生成密钥对
        KeyPair kp=kpg.genKeyPair();
        //获取公钥和私钥
        PublicKey pbkey=kp.getPublic();
        PrivateKey prkey=kp.getPrivate();
        //  保存公钥
        FileOutputStream  f1=new FileOutputStream("Skey_RSA_pub.dat");
        ObjectOutputStream b1=new  ObjectOutputStream(f1);
        b1.writeObject(pbkey);
        //  保存私钥
        FileOutputStream  f2=new FileOutputStream("Skey_RSA_priv.dat");
        ObjectOutputStream b2=new  ObjectOutputStream(f2);
        b2.writeObject(prkey);
    }
}

 

import java.security.interfaces.*;
import java.math.*;
import java.io.*;
public class Enc_RSA {
    public static void main(String args[]) throws Exception{
        String s="Hello World!";
        // 获取公钥及参数e,n
        FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        RSAPublicKey  pbk=(RSAPublicKey)b.readObject( );
        BigInteger e=pbk.getPublicExponent();
        BigInteger n=pbk.getModulus();
        System.out.println("e= "+e);
        System.out.println("n= "+n);
        // 获取明文整数 m
        byte ptext[]=s.getBytes("UTF8");
        BigInteger m=new BigInteger(ptext);
        // 计算密文c,打印
        BigInteger c=m.modPow(e,n);
        System.out.println("c= "+c);
        // 保存密文
        String cs=c.toString( );
        BufferedWriter out=
                new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream("Enc_RSA.dat")));
        out.write(cs,0,cs.length( ));
        out.close( );
    }
}

 

 

 

import java.security.interfaces.*;
import java.math.*;
import java.io.*;
public class Dec_RSA{
    public static void main(String args[]) throws Exception{
        //读取密文
        BufferedReader in=
                new BufferedReader(new InputStreamReader(
                        new FileInputStream("Enc_RSA.dat")));
        String ctext=in.readLine();
        BigInteger c=new BigInteger(ctext);
        //读取私钥
        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();
        System.out.println("d= "+d);
        System.out.println("n= "+n);
        BigInteger m=c.modPow(d,n);
        //显示解密结果
        System.out.println("m= "+m);
        byte[] mt=m.toByteArray();
        System.out.println("PlainText is ");
        for(int i=0;i<mt.length;i++){
            System.out.print((char) mt[i]);
        }
    }
}

 

 运行结果截图:

 

 

 使用密钥协定创建共享密钥代码部分:

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Key_DH.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/KeyAgree.java

 

import java.io.*;
import java.math.*;
import java.security.*;
import javax.crypto.spec.*;

public class Key_DH{
    //三个静态变量的定义从
// C:\j2sdk-1_4_0-doc\docs\guide\security\jce\JCERefGuide.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);
    }
}  

 

import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class KeyAgree{
    public static void main(String args[ ]) throws Exception{
        // 读取对方的DH公钥
        FileInputStream f1=new FileInputStream(args[0]);
        ObjectInputStream b1=new ObjectInputStream(f1);
        PublicKey  pbk=(PublicKey)b1.readObject( );
//读取自己的DH私钥
        FileInputStream f2=new FileInputStream(args[1]);
        ObjectInputStream b2=new ObjectInputStream(f2);
        PrivateKey  prk=(PrivateKey)b2.readObject( );
        // 执行密钥协定
        KeyAgreement ka=KeyAgreement.getInstance("DH");
        ka.init(prk);
        ka.doPhase(pbk,true);
        //生成共享信息
        byte[ ] sb=ka.generateSecret();
        for(int i=0;i<sb.length;i++){
            System.out.print(sb[i]+",");
        }
        SecretKeySpec k=new  SecretKeySpec(sb,"DESede");
    }
}  

 

 

运行结果截图:

 

 

 Java摘要算法-MD5代码部分:

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/DigestPass.java

import java.security.*;
public class DigestPass{
    public static void main(String args[ ]) throws Exception{
        String x=args[0];
        MessageDigest m=MessageDigest.getInstance("MD5");
        m.update(x.getBytes("UTF8"));
        byte s[ ]=m.digest( );
        String result="";
        for (int i=0; i<s.length; i++){
            result+=Integer.toHexString((0x000000ff & s[i]) |
                    0xffffff00).substring(6);
        }
        System.out.println(result);
    }
}

 

运行结果截图:

 

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

20202304何锐编写复数计算器

20202315王梦欣编写有理数计算器(一开始的代码没有加入循环,只能计算一次,后续改进加入了循环)

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Complex.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Plural.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Rational.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/RationalTest.java

有理数计算器产品代码:

public class Rational {
    private long num=0;//分子
    private long den=1;//分母
    //构造函数
    public Rational(){
        this(0,1);
    }
    public Rational (long num,long den){
        long gcd = gcd(num,den);
        this.num= ((den>0)? 1 : -1)*num / gcd;
        this.den=Math.abs(den)/gcd;
    }
    //求最大公约数,便于简化有理数
    private static long gcd(long n, long d){
        long n1=Math.abs(n);
        long n2=Math.abs(d);
        int gcd=1;
        for(int k=1;k<=n1&&k<=n2;k++){
            if(n1%k==0&&n2%k==0){
                gcd=k;
            }
        }
        return gcd;
    }
    //生成器

    public long getNum() {
        return num;
    }
    public long getDen() {
        return den;
    }
    //实现加法
    public Rational add(Rational secondRational){
        long n=num*secondRational.getDen()+den*secondRational.getNum();
        long d=den*secondRational.getDen();
        return new Rational(n,d);
    }
    //实现减法
    public Rational sub(Rational secondRational){
        long n=num*secondRational.getDen()-den*secondRational.getNum();
        long d=den*secondRational.getDen();
        return new Rational(n,d);
    }
    //实现乘法
    public Rational mul(Rational secondRational){
        long n=num*secondRational.getNum();
        long d=den*secondRational.getDen();
        return new Rational(n,d);
    }
    //实现除法
    public Rational div(Rational secondRational){
        long n=num*secondRational.getDen();
        long d=den*secondRational.num;
        return new Rational(n,d);
    }
    //重写toString类
    public String toString(){
        if(den==1){
            return num+"";
        }else{
            return num+"/"+den;
        }
    }
}
import java.util.Scanner;

public class RationalTest extends Rational {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        for (; ; ) {
            System.out.println("请用户输入第一个分数的分子和分母:");
            int a = input.nextInt();
            int b = input.nextInt();
            Rational data1 = new Rational(a, b);
            System.out.println("请用户输入要进行运算的运算符(+ - * /)");
            String operation = input.next();
            System.out.println("请用户输入第二个分数的分子和分母:");
            a = input.nextInt();
            b = input.nextInt();
            Rational data2 = new Rational(a, b);
            Rational rational = new Rational();
            switch (operation) {
                case "+":
                    rational = data1.add(data2);
                    break;
                case "-":
                    rational = data1.sub(data2);
                    break;
                case "*":
                    rational = data1.mul(data2);
                    break;
                case "/":
                    rational = data1.div(data2);
                    break;
            }
            System.out.println("运算结果为:" + rational.toString());
            System.out.println("是否要继续,y/n");
            Scanner scan = new Scanner(System.in);
            String ss = scan.next();
            if (ss.equals("n")) {
                break;
            }
        }
    }
}

运行结果截图:

 

 

 

 (四)远程有理数计算器

20202304何锐编程实现客户端,20202315王梦欣实现服务器端。

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Client2.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Sever2.java

远程有理数计算器客户端代码:

 

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client2 extends Rational {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost",2304);
        OutputStream outputStream = socket.getOutputStream();
        PrintWriter printWriter = new PrintWriter(outputStream);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
        Scanner input = new Scanner(System.in);
        System.out.println("输入第一个数的分子和分母");
        int x = input.nextInt();
        int y = input.nextInt();
        Rational rational1 = new Rational(x,y);
        System.out.println("输入第二个数字的分子和分母");
        x = input.nextInt();
        y = input.nextInt();
        Rational rational2 = new Rational(x,y);
        System.out.println("输入运算符");
        Scanner s = new Scanner(System.in);
        String op = s.next();
        String m1 = String.valueOf(rational1.getNum());
        String m2 = String.valueOf(rational1.getDen());
        String n1 = String.valueOf(rational2.getNum());
        String n2 = String.valueOf(rational2.getDen());
        String line = op + " " + m1 + " " + m2 + " " + n1 + " " + n2;

        outputStreamWriter.write(line);
        outputStreamWriter.flush();
        socket.shutdownOutput();
        String reply = null;
        while (!((reply = bufferedReader.readLine()) ==null)){
            System.out.println("接收服务器的信息为:" + reply);
        }
        bufferedReader.close();
        inputStream.close();
        outputStreamWriter.close();
        printWriter.close();
        outputStream.close();
        socket.close();
    }
}

 

 

远程有理数计算器服务器端代码:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;


class server2 extends Rational {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(2304);
        Socket socket = serverSocket.accept();//防止监听
        InputStream in = socket.getInputStream();
        InputStreamReader isr
                = new InputStreamReader(in, StandardCharsets.UTF_8);
        BufferedReader br
                = new BufferedReader(isr);

        Scanner scanner = new Scanner(System.in);
        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);

        String line = null;
        while ((line = br.readLine()) != null) {

            String[] strs = line.split(" ");
            String s = strs[0];
            long X1 = Long.parseLong(strs[1]);
            long X2 = Long.parseLong(strs[2]);
            long X3 = Long.parseLong(strs[3]);
            long X4 = Long.parseLong(strs[4]);
            System.out.println("客户端问:" +X1+"/"+X2+s+X3+"/"+X4);
            Rational rational1 = new Rational(X1, X2);
            Rational rational2 = new Rational(X3, X4);
            String reply = null;
            switch (s) {
                case "+":
                    reply = String.valueOf(rational1.add(rational2));
                    pw.println(reply);
                    break;
                case "-":
                    reply = String.valueOf(rational1.sub(rational2));
                    pw.println(reply);
                    break;
                case "*":
                    reply = String.valueOf(rational1.mul(rational2));
                    pw.println(reply);
                    break;
                case "/":
                    reply = String.valueOf(rational1.div(rational2));
                    pw.println(reply);
                    break;
            }

            socket.close();
            serverSocket.close();
        }
    }
}

 

 

运行结果截图:

 

 

 

 

 

 

 

 (五)远程复数计算器

20202304何锐编程实现服务器端,20202315王梦欣实现客户端。

码云网址:https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Client1.java

https://gitee.com/besti2023javads/wang-mengxin-20202315/blob/%E5%AE%9E%E9%AA%8C%E5%9B%9B/Sever1.java

远程复数计算器客户端代码:

 

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client1 extends Complex {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost",2315);
        OutputStream outputStream = socket.getOutputStream();
        PrintWriter printWriter = new PrintWriter(outputStream);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
        Scanner input = new Scanner(System.in);
        System.out.println("输入第一个数的实部和虚部");
        int x = input.nextInt();
        int y = input.nextInt();
        Complex complex1 = new Complex(x, y);
        System.out.println("输入第二个数字的实部和虚部");
        x = input.nextInt();
        y = input.nextInt();
        Complex complex2 = new Complex(x, y);
        System.out.println("输入运算符");
        Scanner s = new Scanner(System.in);
        String op = s.next();
        String m1 = String.valueOf(complex1.getRealPart());
        String m2 = String.valueOf(complex1.getImagePart());
        String n1 = String.valueOf(complex2.getRealPart());
        String n2 = String.valueOf(complex2.getImagePart());
        String line = op + " " + m1 + " " + m2 + " " + n1 + " " + n2;

        outputStreamWriter.write(line);
        outputStreamWriter.flush();
        socket.shutdownOutput();
        String reply = null;
        while (!((reply = bufferedReader.readLine()) ==null)){
            System.out.println("接收服务器的信息为:" + reply);
        }
        bufferedReader.close();
        inputStream.close();
        outputStreamWriter.close();
        printWriter.close();
        outputStream.close();
        socket.close();
    }
}

 

远程复数计算器服务器端代码:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;


public class Sever1 extends Complex {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(2315);//新建服务器,端口:2315
        Socket socket = serverSocket.accept();//防止监听
        InputStream in = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
        BufferedReader br = new BufferedReader(isr);
        Scanner scanner = new Scanner(System.in);
        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);

        String line = null;
        while ((line = br.readLine()) != null) {

            String[] strs = line.split(" ");
            String s = strs[0];
            double X1 = Double.parseDouble(strs[1]);
            double X2 = Double.parseDouble(strs[2]);
            double X3 = Double.parseDouble(strs[3]);
            double X4 = Double.parseDouble(strs[4]);
            Complex complex1 = new Complex(X1, X2);
            Complex complex2 = new Complex(X3, X4);
            System.out.println("客户端问:" +"("+X1+"+"+X2+"i"+")"+s+"("+X3+"+"+X4+"i"+")");
            String reply = null;
            switch (s) {
                case "+":
                    reply = String.valueOf(complex1.Add(complex2));
                    pw.println(reply);
                    break;
                case "-":
                    reply = String.valueOf(complex1.Sub(complex2));
                    pw.println(reply);
                    break;
                case "*":
                    reply = String.valueOf(complex1.Mul(complex2));
                    pw.println(reply);
                    break;
                case "/":
                    reply = String.valueOf(complex1.Div(complex2));
                    pw.println(reply);
                    break;
            }

            socket.close();
            serverSocket.close();
        }
    }
}

运行结果截图:

 

 

 

 

 

## 3. 实验过程中遇到的问题和解决过程

- 问题1:第一次运行凯撒密码的时候,持续出错但是找不到程序中的错误
- 问题1解决方案:将出错的错误提示在百度上搜索过后发现由于args[0],args[1]的存在需要设置参数,不能直接run。
- 问题2:有理数计算器程序RationalTest的运行过程中一直无法正确调用Rational,无法输出最终结果
- 问题2解决方案:多次调试查找错误所在,多次debug以致正确运行
- 问题3:编写远程计算器过程中想在服务器端显示客户端的需求,一开始一直报错
- 问题3解决方案:搜索学习后发现需要通过抽取一些关键量,重新组合写出



## 其他(感悟、思考等)

Java和密码学好复杂,哭... 一个对称加密前前后后四个代码,敲到难受,敲到头秃。

 

 

------------恢复内容结束------------

posted @ 2021-10-24 23:39  王梦欣  阅读(160)  评论(0编辑  收藏  举报