课程:《程序设计与数据结构》
班级: 1723
姓名: 方艺雯
学号:20172314
实验教师:王志强
实验日期:2018年6月13日
必修/选修: 必修
1、实验内容及要求
-
实验五-1
两人一组结对编程:
0. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA- 结对实现中缀表达式转后缀表达式的功能 MyBC.java
- 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
- 上传测试代码运行结果截图和码云链接
-
实验五-2
结对编程:1人负责客户端,一人负责服务器
0. 注意责任归宿,要会通过测试证明自己没有问题- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
- 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
-
实验五-3
加密结对编程:1人负责客户端,一人负责服务器
0. 注意责任归宿,要会通过测试证明自己没有问题- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
- 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
-
实验五-4
密钥分发结对编程:1人负责客户端,一人负责服务器
0. 注意责任归宿,要会通过测试证明自己没有问题- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
-
实验五-5
实验五 网络编程与安全-5
完整性校验结对编程:1人负责客户端,一人负责服务器
0. 注意责任归宿,要会通过测试证明自己没有问题- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
实验过程及结果
实验5-1
-
过程
利用博客中的MyDC、MyBC的代码,并编写计算类,MyBC是将中缀式转为后缀式,MyDC是计算后缀式的值。计算类代码:
package test; import java.util.*; public class Calculator { public static void main(String[] args) { String string; int result; MyBC a = new MyBC(); MyDC b = new MyDC(); System.out.println("请输入中缀式:"); Scanner xxx = new Scanner(System.in); string = xxx.nextLine(); a.conversion(string); System.out.println("后缀表达式是:"+ a.getMessage()); result = b.evaluate(a.getMessage()); System.out.println("式子的结果是:"+ result); } }
-
实验结果
实验5-2
- 过程
我负责的是客户端,在实验5-1的基础上,将客户端与服务端连接后,关键代码是:
服务端的关键代码是:Scanner xxx = new Scanner(System.in); String a; System.out.println("请输入中缀表达式:"); a = xxx.nextLine(); MyBC b = new MyBC(); b.conversion(a); String info1 =b.getMessage(); String info = new String(info1.getBytes("utf-8")); // printWriter.write(info); // printWriter.flush(); outputStreamWriter.write(info); outputStreamWriter.flush(); socket.shutdownOutput();
MyDC b = new MyDC(); String info=null; String result = ""; int xxx; info = bufferedReader.readLine(); xxx = b.evaluate(info); result = Integer.toString(xxx); System.out.println(result);
- 实验结果
实验5-3
-
过程
- 实现DES加密的主要步骤:
- 对称密钥的生成和保存
- 使用对称密钥进行加密和解密
- 从文件中获取加密时使用的密钥,使用密钥进行解密
- 实现DES加密的主要步骤:
-
实验结果
实验5-4
- 过程
- 执行密钥协定的标准算法是DH算法(Diffie-Hellman算法),Diffie-Hellman是一种建立密钥的方法,而不是加密方法。然而,它所产生的密钥可用于加密、进一步的密钥管理或任何其它的加密方式。
- 分为以下两步:
- 创建DH公钥和私钥,保存在两个文件中
- 将两个密钥合并,创建共享密钥
- 实验结果
实验5-5
-
过程
- 可以使用Java计算指定字符串的消息摘要。java.security包中的MessageDigest类提供了计算消息摘要的方法,首先生成对象,执行其update()方法可以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。
- 加密:
public class DigestPass{ public static String DP(String s1) throws Exception{ String x=s1; 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);//将加密结果转换为16进制字符串 } return result;//返回加密后的结果 } }
-
实验结果
遇到的问题及解决
-
问题一:在做实验5-3时,尝试得出密钥然后发给小伙伴,以“,”作为分割线结果报错
-
问题一解决:错误的原因在于“,”与数字之间还有空格,解决方法为把字符串中的空格删去,或者把标记改为“, ”
-
问题二:产生异常“connection reset”
-
问题二解决:网上查找解决办法,有如下问题参考:什么情况下会产生Connection reset
第1个异常是java.net.BindException:Address already in use: JVM_Bind。该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时。异常的原因是以为与port一样的一个端口已经被启动,并进行监听。此时用netstat –an命令,可以看到一个Listending状态的端口。只需要找一个没有被占用的端口就能解决这个问题。
第2个异常是java.net.ConnectException: Connection refused: connect。该异常发生在客户端进行new Socket(ip, port)操作时,该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端口进行监听。出现该问题,首先检查客户端的ip和port是否写错了,如果正确则从客户端ping一下服务器看是否能ping通,如果能ping通(服务服务器端把ping禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动,这个肯定能解决这个问题。
第3个异常是java.net.SocketException: Socket is closed,该异常在客户端和服务器均可能发生。异常的原因是己方主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作。
第4个异常是java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)。该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。
第5个异常是java.net.SocketException: Broken pipe。该异常在客户端和服务器均有可能发生。在第4个异常的第一种情况中(也就是抛出SocketExcepton:Connect reset by peer:Socket write error后),如果再继续写数据则抛出该异常。前两个异常的解决方法是首先确保程序退出前关闭所有的网络连接,其次是要检测对方的关闭连接操作,发现对方关闭连接后自己也要关闭该连接。
发现是有第四个异常的可能,没有按照正确的连接步骤,所以一个可能关闭了,另一个就无法传输数据。在进行客户端与服务端的连接时,首先要注意正确填写地址与端口,其次是先运行服务端,后运行客户端。
-
问题三:* 在做这个实验时,根据老师提示,想着把密钥发给服务端即可,但是用qq发送总会改变密钥并且添加表情。
-
问题三解决:尝试了各种办法,最后将密钥单独运行出来,就可以将一个数字组成的字符串发给服务端。不过最终这个方法总是出错就放弃了。
其他
这次实验结合了密码算法,由于对密码不是很了解,所以实验还是有一点难度的,但学习之后对客户端和服务端的连接有了更深的理解,对密码的一些相关算法有了全面的认识。