北京电子科技学院(BESTI)
实 验 报 告
课程:Java程序设计 班级:1353 姓名:陈巧然 学号:20135310
成绩: 指导教师:娄嘉鹏 实验日期:2015.6.9
实验密级: 预习程度: 实验时间:15:20-18:00
仪器组次:10 必修/选修: 实验序号:4
实验名称: TCP传输及加解密
实验内容:
1.运行教材上TCP代码,结对进行,一人服务器,一人客户端;
2.利用加解密代码包,编译运行代码,一人加密,一人解密;
3.集成代码,一人加密后通过TCP发送;
注:加密使用AES或者DES/AES或者DES加密密钥key并发送,使用服务器的公钥加密/公钥算法使用RSA或DH/检验发送信息的完整性使用MD5或者SHA3;
4.用Git进行版本控制。
5.完成Blog
实验仪器:
名称 |
型号 |
数量 |
PC | Macbook Air(win7系统) |
1 |
我的结对伙伴是20135311傅冬菁,
博客地址http://www.cnblogs.com/bushifudongjing/
我负责服务器,她负责客户端
一、代码
服务器:
import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class MyServer {
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
ServerSocket sc = null;
ServerSocket sc1 = null;
Socket socket=null;
Socket socket1=null;
try {
sc= new ServerSocket(4431);//创建服务器套接字
sc1= new ServerSocket(4430);//创建服务器套接字
System.out.println("端口号:" + sc.getLocalPort());
System.out.println("服务器1已经启动...");
System.out.println("端口号:" + sc1.getLocalPort());
System.out.println("服务器2已经启动...");
socket = sc.accept(); //等待客户端连接
System.out.println("已经建立连接");
socket1 = sc1.accept(); //等待客户端连接
System.out.println("已经建立1连接");
//获得网络输入流对象的引用
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader in1 = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
////获得网络输出流对象的引用
System.out.print("已接收\n");
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
String aline=in.readLine();//读取客户端传送来的数据
String aline1=in1.readLine();
System.out.print("写入文件中...\n");
byte [] bytes = aline.getBytes("GB2312");
byte [] bytes1 = aline1.getBytes("GB2312");
aline = new String(bytes, "GB2312");
aline1 = new String(bytes1, "GB2312");
FileOutputStream s=new FileOutputStream("key1.dat");
s.write(bytes);
FileOutputStream s1=new FileOutputStream("SEnc.dat");
s1.write(bytes1);
System.out.print("已写入文件\n");
//生成解密密钥
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);
System.out.print("生成解密密钥\n");
// 打印密钥编码中的内容
for(int i=0;i<kb.length;i++){
// System.out.print(kb[i]+",");
}
//解密
FileInputStream a=new FileInputStream("SEnc.dat");
int num=a.available();
byte[ ] ctext=new byte[num];
a.read(ctext);
FileInputStream f1=new FileInputStream("keykb1.dat");
int num2=f1.available();
byte[ ] keykb=new byte[num2];
f1.read(keykb);
SecretKeySpec e=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,"GB2312");
System.out.print("解密中...\n");
System.out.println(p);
//返回
System.out.println("从客户端接收到信息为:"+p); //通过网络输出流返回结果给客户端
out.println(p);
out.close();
in.close();
sc.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
截图:
二、遇到的问题及怎样解决:
1、将程序包中程序整合时经常容易出现重定义和变量名占用的问题,此时只需要注销掉重复定义的部分或者更改变量名即可,但要注意后来引用部分也需要更改变量名。
2、同时将加密密钥和密文文件打包发送时服务器无法区分两个数据流。重新定义一个新端口4430,将两个文件通过两个不同的端口4431和4430分别发送。
3、文件发送后string型数据无法转换为FileOutputStream型数据,无法写入文件。通过查询资料,按照 GB2312 得到字节(得到多字节字符串)
byte [] bytes = string.getBytes("GB2312");
从字节按照 GB2312 得到 UNICODE 字符串
string = new String(bytes, "GB2312");
用 Stream 类写入已经按照指定编码转化好的字节串
OutputStream os = new FileOutputStream("1.txt");
os.write(bytes);
os.close();
三、实验体会
1.PSP时间
步骤 |
耗时 |
百分比 |
需求分析 |
1.5h |
21.4% |
设计 |
2h |
28.6% |
代码实现 |
2h |
28.6% |
测试 |
1h |
14.3% |
分析总结 |
0.5h |
7.1% |
2.感想
本次实验是我和搭档结对完成的,虽然大部分代码是现成的,但是整合起来却十分的麻烦,要把DES加密、RSA加密的代码整合在一个程序中并且要编译成功是一件十分困难的事情,一不小心就会漏洞百出,而在网络连接,传送,反馈上也有很多很难的地方,遇到有问题的地方往往需要上网翻阅很多资料才能找到适合的解决方案,在对代码的不断调试、改进、调试、改进后编译成功,程序完美联通并运行的时候真是神清气爽。这就是程序猿的乐趣所在。