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编程
客户端代码:
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算法代码部分
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
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代码部分:
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/Plural.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/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/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和密码学好复杂,哭... 一个对称加密前前后后四个代码,敲到难受,敲到头秃。
------------恢复内容结束------------