博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

------------恢复内容开始------------

 

# 20202304 2021-2022 《数据结构与面向对象程序设计》实验四报告

课程:《程序设计与数据结构》
班级: 2023
姓名: 何锐
学号:20202304
实验教师:王志强
实验日期:2021年10月14日
必修/选修: 必修

 

## 实验内容及过程

(一)Java Socket编程

1.学习蓝墨云上教材《Java和Android编程》“第16章 输入/输出 ”和“第22章 网络”,学习JavaSocket编程
2.结对编程。结对伙伴A编写客户端SocketClient.java,结对伙伴B编写服务器端。

结对伙伴为20202315王梦欣。我在(一)中负责客户端。

服务器端:

 

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();
    }
}

 

客户端:

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();

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Server.java

           https://gitee.com/besti2023javads/hr20202304/blob/master/SocketClient.java

测试截图:

服务器

客户端

二)Java和密码学

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

以结对的方式完成Java密码学相关内容的学习(帖子中所有代码和相关知识点需要学习)。

 

凯撒密码

 

它将字母表中的字母移动一定位置而实现加密。

 

在密码学中存在着各种各样的置换方式,但所有不同的置换方式都包含2个相同的元素。密钥和协议(算法)。凯撒密码的密钥是3,算法是将普通字母表中的字母用密钥对应的字母替换。置换加密的优点就在于它易于实施却难于破解. 发送方和接收方很容易事先商量好一个密钥,然后通过密钥从明文中生成密文,即是敌人若获取密文,通过密文直接猜测其代表的意义,在实践中是不可能的。

 

凯撒密码的加密算法极其简单。其加密过程如下:

 

在这里,我们做此约定:明文记为m,密文记为c,加密变换记为E(k1,m)(其中k1为密钥),解密变换记为D(k2,m)(k2为解密密钥)(在这里k1=k2,不妨记为k)。凯撒密码的加密过程可记为如下一个变换:

 

c≡m+k mod n (其中n为基本字符个数)

 

同样,解密过程可表示为:
m≡c+k mod n (其中n为基本字符个数)

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Ceaser.java

实现代码:

import java.lang.*;
public class Ceaser {        //凯撒密码加密
    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算法

  • 对称密钥的生成和保存

本实例给出Java中创建对称密钥的步骤,并通过对象序列化方式保存在文件中。

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Skey_DES.java

   https://gitee.com/besti2023javads/hr20202304/blob/master/Skey_kb.java

   https://gitee.com/besti2023javads/hr20202304/blob/master/SEnc.java

   https://gitee.com/besti2023javads/hr20202304/blob/master/SDec.java

实现代码:

Skey_DES,在当前目录下将生成文件key1.dat,其中包含的密钥可以用于使用Triple-DES算法的加密和解密。

 import java.io.*;
import javax.crypto.*;
    public class Skey_DES{
        public static void main(String args[])
                throws Exception{
            KeyGenerator kg=KeyGenerator.getInstance("DESede");//获取密钥生成器,算法为DESede
            kg.init(168);//初始化密钥生成器,根据算法使用不同的密钥长度
            SecretKey k=kg.generateKey( );//生成密钥
            FileOutputStream  f=new FileOutputStream("key1.dat");
            ObjectOutputStream b=new  ObjectOutputStream(f);
            b.writeObject(k);
        }
    }

输入java Skey_kb 运行程序,在程序的当前目录中将产生文件名为keykb1.dat的文件

import java.io.*;
import java.security.*;
public class Skey_kb{
    public static void main(String args[]) throws Exception{
        //获取密钥(由于readObject( )返回的是Object类型,因此需要强制转换成Key类型。)
        FileInputStream f=new FileInputStream("key1.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        Key k=(Key)b.readObject( );
        //获取主要编码格式,执行SecretKey类型的对象k的getEncoded( )方法,返回的编码放在byte类型的数组中。
        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]+",");
        }
    }
}

密文同时保存在SEnc.dat文件中,将其提供给需要的人时,需要同时提供加密时使用的密钥,这样收到SEnc.dat中密文的人才能够解密文件中的内容。

import javax.crypto.*;
public class SEnc{
    public static void main(String args[]) throws Exception{
        String s="Hello java";
        //从文件中获取密钥
        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);
    }
}

测试截图:

Java非对称加密-RSA算法

使用Java中定义好的类创建RSA公钥和私钥。 Java的KeyPairGenerator类提供了一些方法来创建密钥对以便用于非对称加密,密钥对创建好后封装在KeyPair类型的对象中,在KeyPair类中提供了获取公钥和私钥的方法。

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Skey_RSA.java

   https://gitee.com/besti2023javads/hr20202304/blob/master/Enc_RSA.java

      https://gitee.com/besti2023javads/hr20202304/blob/master/Dec_RSA.java

实现程序:

import java.io.*;
import java.security.*;

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.io.*;
public class Enc_RSA{
    public static void main(String args[]) throws Exception{
        String s="Hello Herren!";
        // 获取公钥及参数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.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]);
        }
    }
}

测试截图:

Java摘要算法- MD5

使用Java计算指定字符串的消息摘要。
java.security包中的MessageDigest类提供了计算消息摘要的方法,

首先生成对象,执行其update()方法可以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/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");
        //生成对象并指定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);
    }
}

测试截图:

实验四 (3)编写有理数/复数计算器

结对编程,结对伙伴A编写有理数计算器。结对伙伴B编写复数计算器。伙伴为20202315王梦欣,编写了有理数计数器而我做了复数计数器。

复数计算器:

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Plural.java

实现程序:

public class Complex {
    // 定义属性并生成getter,setter
    private double RealPart;
    private double ImagePart;
    // 定义构造函数
    public Complex(){

    }
    public Complex(double R, double I){
        this.RealPart = R;
        this.ImagePart = I;
    }

    public double getRealPart() {
        return RealPart;
    }

    public void setRealPart(double realPart) {
        RealPart = realPart;
    }

    public double getImagePart() {
        return ImagePart;
    }

    public void setImagePart(double imagePart) {
        ImagePart = imagePart;
    }


    public boolean equals(Object obj){
        if(this == obj) {
            return true;
        }
        if(!(obj instanceof Complex)) {
            return false;
        }
        Complex complex = (Complex) obj;
        if(complex.RealPart != ((Complex) obj).RealPart) {
            return false;
        }
        if(complex.ImagePart != ((Complex) obj).ImagePart) {
            return false;
        }

        return true;
    }
    public String toString()   {
        String string = "";
        if (ImagePart > 0)
            string =  RealPart + "+" + ImagePart + "i";
        if (ImagePart == 0)
            string =  RealPart + "";
        if (ImagePart < 0)
            string = RealPart + " " + ImagePart + "i";
        return string;
    }

    // 定义公有方法:加减乘除
    Complex ComplexAdd(Complex a) {
        return  new Complex(RealPart+a.RealPart,ImagePart+a.ImagePart);
    }
    Complex ComplexSub(Complex a) {
        return new Complex(RealPart-a.RealPart,ImagePart-a.ImagePart);
    }
    Complex ComplexMulti(Complex a) {
        return new Complex(RealPart*a.RealPart-ImagePart*a.ImagePart,ImagePart*a.RealPart+RealPart*a.ImagePart);
    }
    Complex  ComplexDiv(Complex a) {
        Complex d = new Complex();
        d.RealPart = (this.RealPart * a.RealPart + this.ImagePart * a.ImagePart)/(a.RealPart*a.RealPart+a.ImagePart*a.ImagePart);
        d.ImagePart = (this.ImagePart * a.RealPart - this.RealPart * a.ImagePart)/(a.RealPart*a.RealPart+a.ImagePart*a.ImagePart);
        return d;
    }

}

 

import java.util.Scanner;
public class Plural extends Complex{
    public Plural(){}
    public Plural(double R,double I){
        super(R, I);
    }
    public static void main(String[] args) {
    System.out.println("这是一个复数计算器");
    for(;;){

        System.out.println("请输入第一个复数的实部和虚部");
        Scanner scan1=new Scanner(System.in);
        int x = scan1.nextInt();
        int y = scan1.nextInt();
        Complex complex1 = new Complex(x,y);
        System.out.println("请输入第二个复数的实部和虚部");
        Scanner scan2=new Scanner(System.in);
        int a = scan2.nextInt();
        int b = scan2.nextInt();
        Complex complex2 = new Complex(a,b);
        System.out.println("请输入你想要的算数符号,如+ - * /");
        Scanner s = new Scanner(System.in);
        String op = s.next();
        switch (op){
            case"+":
                System.out.println(complex1.Add(complex2));
                break;
            case"-":
                System.out.println(complex1.Sub(complex2));
                break;
            case"*":
                System.out.println(complex1.Mul(complex2));
                break;
            case"/":
                System.out.println(complex1.Div(complex2));
                break;
        }
        System.out.println("是否要继续,y/n");
        Scanner scan=new Scanner(System.in);
        String ss =scan.next();
        if(ss.equals("n")){
            break;
        }
    }
    }
}

 

测试截图:

 

 

 

有理数计算器:

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Rational.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);
        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());

    }
}

 

测试截图:

 

 

 

 

实验四 (4)远程有理数计算器

 结对编程,结对伙伴A编程实现客户端,结果伙伴B实现服务器端。

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Sever2.java

      https://gitee.com/besti2023javads/hr20202304/blob/master/Client2.java

实现程序:

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();
        }
    }
}
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("172.16.230.134",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();
    }
}

实验截图:

 

 

 

 实验四 (5)远程复数计算器

结对编程,结对伙伴B编程实现客户端,结果伙伴A实现服务器端。

码云:https://gitee.com/besti2023javads/hr20202304/blob/master/Sever1.java

   https://gitee.com/besti2023javads/hr20202304/blob/master/Client1.java

实现代码:

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) {

            System.out.println("客户端问:" + line);
            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);
            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();
        }
    }
}
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();
    }
}

 

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

问题一:计算器一开始没有使用toString方法重写,导致输出出问题。 后重写解决

问题二:做远程计算器时,一开始不知道改以何种方法传输计算的量。 后把客户端复杂化后解决

问题三:无法解决客户端显示算式的问题,后通过修饰和引用关键量解决。

 

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

感觉这次实验的难度和复杂度都比较大,尤其是一开始不知道如何把io与服务器连接起来,而计算器的内容又联系到了继承封装等,算是一次比较综合的考察实验,要好好掌握并整理这次实验的问题和收获,从根本上更了解了对java的认识,也增加了对java的兴趣哈哈哈哈哈哈。(唯一的不好就是,服务器一报错就是贼长的一串,得挨个翻译23333).

 

 

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