20162302 实验五《网络编程与安全》实验报告
实 验 报 告
课程:程序设计与数据结构
姓名:杨京典
班级:1623
学号:20162302
实验名称:网络编程与安全
实验器材:装有IdeaU的联想拯救者80RQ
实验目的与要求:
1.中缀式转后缀式的实现
2.客户端-服务器传输的尝试
3.在传输的工程中加入加密和解密算法
4.传输密钥
实验内容、步骤与体会:
实验内容:
中缀式转后缀式的实现
这个实验在之间的四则运算项目里面是直接会用到的,当时只是在网上找的代码随便改了改就直接用的,后来导致了在转制的时候会直接忽略括号的存在,对于四则运算的整个项目有着一定的影响。遗憾的是我在项目结束以后才发现所存在的这个问题,所以我决定自己亲自写一个转制的代码。
主体思路是用StringTokenizer
中的nextToken
方法来实现的扫描整个式子,再用switch
循环结构判断不同的符号和数字,再给与不同的操作,根据的是老师给的博客里面的转换方法。
case "/":
while (!stack.isEmpty() && (stack.get(stack.size()-1).equals("*") || stack.get(stack.size()-1).equals("/")))
suffix += stack.pop();
suffix += " ";
stack.push(c + "");
break;
上面的代码是用于判断优先级并执行相应操作的代码。
实现扫描也可以使用charAt
来判断字符,不过nextToken
返回值是String
,而charAt
返回值是char
客户端-服务器传输的尝试
这次实验中最基本的地方就是建立这一部分,成功建立客户端和服务器才能继续进行下一步,我负责的客户端部分
客户端主要由下面几部分组成
1、创建客户端Socket,指定服务器地址和端口
Socket socket=new Socket("127.0.0.1",2302);
2、获取输出流,向服务器端发送信息
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 由系统标准输入设备构造BufferedReader对象
PrintWriter write = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
3、获取输入流,并读取服务器端的响应信息
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
4、关闭资源
write.close(); // 关闭Socket输出流
in.close(); // 关闭Socket输入流
socket.close(); // 关闭Socket
在实验的时候直接套用自己之前写好的类就可以完成转制,然后传送给服务器
在传输的工程中加入加密和解密算法
在这项实验中使用的是老师博客中的实验代码,都是可执行的文件,所以我的工作是把它们转换成一个类,然后在客户端中调用
比如
import java.io.*;
import java.security.*;
import javax.crypto.*;
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);
}
}
这是老师给出的加密方法,目的是把s
这个句子加密后输出到SEnc.dat
中,其实可以直接将里面的加密方法植入到客户端,但是在这次的试验中我想练习一下对于现有的代码进行改造的能力,比如在之前为了适应自己项目的需求,将后缀式计算的结果返回值由int换成String
,在后续完善的过程中有很大的便利。
首先是返回值的格式,在网络传输的过程中String
较为便捷,所以返回值就要设置为String
,而生成的是byte[]
型,所以就需要一个转换byte[]
型到String
型的类
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
在加密和解密的时候显示结果也很多余,所以也可以去掉
public String senc(String s) throws Exception{
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");
System.out.println("");
byte ctext[]=cp.doFinal(ptext);
return parseByte2HexStr(ctext);
}
传输密钥
在传输密钥的时候也可以用类似的方式生成密钥并传输
感想
这次实验是我感触最深的,之前的实验难度都很高,这次也不例外,基本上一次实验接触一个新领域,这次的实验时间紧,任务重。现在是期末阶段,有很多科目都结课了,相应的也会有一些需要上交的论文。在这周还有一个马尔科夫的结对编程项目,也有一定的难度。这周五我还参加了一个四系主办的一个讲座,讲座持续了两个小时,原定计划还有送老会,但是考虑到还有未完成的实验,也就推掉了。这次实验做的非常紧,在做实验的过程中也是各种的失败,心态上也是受到了很大的打击,多次有放弃的打算,但是在服务器和客户端成功连接并完成信息的交换以后,也是很开心的。