20155232 2016-2017-3 《Java程序设计》第10周学习总结
20155232 2016-2017-3 《Java程序设计》第10周学习总结
教材学习内容总结
- 计算机网络
路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控制等,通过光纤、网线等连接将设备连接起来,从而形成了一张巨大的计算机网络。
-
网络概览
-
计算机之间使用共同的语言来通信,称之为协议,协议分为几个层,如图展示了网络中的一些层。
- 超文本传输协议(HTTP)
HTTP是允许WEB服务器和浏览器之间通过互联网发送和接收数据的协议。它是一种请求和响应协议。在HTTP中总是由客户端先建立一个连接并发送一个请求,从而发起一次事务。分为:HTTP响应和HTTP请求。
- java.net.URL
1.URL是互联网资源的唯一地址。HTTP是URL中最常使用的协议。可以使用如下方法解析URL:
2.可以使用URL类的openStream方法读取一个web资源。
- java.net.URLConnection
URLConnection表示到远程机器的一次连接。使用它读取资源并写到一台远程机器中。URLConnection类并没有公共的构造方法,因此无法使用new创建实例。
- java.net.Socket
套接字是一个网络连接的端点。套接字使得应用程序能够从网络读取或者向网络写入信息。位于两台不同的计算机的软件,通过连接来发送和接受数据流,就可以彼此通信。
- java.net.ServerSocket
Socket表示一个“客户端”套接字,当想要连接到一个远程服务器应用的时候,可以构造一个套接字。ServerSocket和socket不同。服务器套接字的角色是,等待客户端的连接请求。一档获得请求,会创建一个socket实例,以处理和客户端的通信。
- Request类
Request类表示一个HTTP请求。该类的实例是通过传入Socket对象获取的java.io.InputStream对象来构造的。
- Response类
代表了一个HTTP响应。Response类有两个公有的方法:setRequest和sendStaticResource方法。etRequest方法用于将一个Request对象传递给Response对象。
教材学习中的问题和解决过程
- 问题一
如何使服务器端支持多个客户端同时工作?
- 解决方法
在服务器端利用多线程。为每一个连接 创建一个线程去处理。一个服务器端一般都需要同时为多个客户端提供通讯,当服务器端接收到一个连接时,启动一个专门的线程处理和该客户端的通讯,这样就可以支持多个客户端。上网搜索了一下在这个链接中有很详细的解释
服务器端支持多个客户端工作
- 问题二
在书中第22章的22.7中提到了await()方法,联想到了wait()方法,那么wait()方法和sleep()方法有什么区别?
- 解决方案
Java中的多线程是一种抢占式的机制而不是分时机制。线程主要有以下几种状态:可运行,运行,阻塞,死亡。抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行。当有多个线程访问共享数据的时候,就需要对线程进行同步。线程中的几个主要方法的比较:
1.Thread类的方法:sleep(),yield()等
2.Object的方法:wait()和notify()等
每个对象都有一个机锁来控制同步访问。Synchronized关键字可以和对象的机锁交互,来实现线程的同步。
由于sleep()方法是Thread类的方法,因此它不能改变对象的机锁。所以当在一个Synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的机锁没有被释放,其他线程仍然无法访问这个对象。
而wait()方法则会在线程休眠的同时释放掉机锁,其他线程可以访问该对象。
代码调试中的问题和解决过程
- 问题一
在老师给的材料中java密码技术
如下程序SDec.java中:
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密码技术中程序:
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);
}
}
按照老师给出的代码运行错误:
- 解决方案
将类名改为
DigestCalc.java
即可使用
java DigestCalc abc
运行,其中命令行参数abc是原始数据,屏幕输出计算后的消息摘要:900150983cd24fb0d6963f7d28e17f72。
代码托管
- 代码提交过程截图:
结对及互评
评分标准(满分10分)
-
从0分加到10分为止
-
正确使用Markdown语法(加1分):
- 不使用Markdown不加分
- 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
- 排版混乱的不加分
-
模板中的要素齐全(加1分)
- 缺少“教材学习中的问题和解决过程”的不加分
- 缺少“代码调试中的问题和解决过程”的不加分
- 代码托管不能打开的不加分
- 缺少“结对及互评”的不能打开的不加分
- 缺少“上周考试错题总结”的不能加分
- 缺少“进度条”的不能加分
- 缺少“参考资料”的不能加分
-
教材学习中的问题和解决过程, 一个问题加1分
-
代码调试中的问题和解决过程, 一个问题加1分
-
本周有效代码超过300分行的(加2分)
- 一周提交次数少于20次的不加分
6 其他加分:
- 周五前发博客的加1分
- 感想,体会不假大空的加1分
- 排版精美的加一分
- 进度条中记录学习时间与改进情况的加1分
- 有动手写新代码的加1分
- 课后选择题有验证的加1分
- 代码Commit Message规范的加1分
- 错题学习深入的加1分
7 扣分: - 有抄袭的扣至0分
- 代码作弊的扣至0分
点评模板:
-
博客中值得学习的或问题:
- xxx
- xxx
- ...
-
代码中值得学习的或问题:
- xxx
- xxx
- ...
-
基于评分标准,我给本博客打分:XX分。得分情况如下:xxx
点评过的同学博客和代码
- 本周结对学习情况
-
结对学习内容
- 一起看老师给的网页链接学习,共同解决代码编译报错问题。
- 讨论分析上周考试留下来的部分没有解决的试题。
- 讨论知识点,交换学习体会和总结学习难点。
- 上周博客互评情况
上周考试错题总结
- 简答(5)你是如何运行P509 ConnectionDemo.java和P513 MessageDAODemo.java的?
下载安装MySQL(或XAMPP),IDE(Eclipse/IDEA/Netbeans)中导入数据库驱动 (1分)
建数据库demo : create schema demo (1 分)
修改P509 ConnectionDemo.java中passwd 改为自己的,openhome的一般不对(1分)
建表:
Use demo;
create TABLE t_message …. (1分)
修改P509 ConnectionDemo.java中MessageDAO dao = new MessageDAO()中的口令 改为自己的,openhome的一般不对(1分)
感悟心得
- 对考试感悟
在这次考试中失分过多,是考试中最差的一次,主要原因是在前面的一个题上浪费的时间过多,导致最后一道大题会做却没得分,因为没有时间了,所以遇到不会的题不能一直纠结浪费时间,应该先做下一题,等做完后再反过来看不会的题,这样就不会导致这种情况的出现了。
- 运行Java 密码学算法中代码
1.体验加解密---凯撒密码
加密过程:c≡m+k mod n (其中n为基本字符个数)
同样,解密过程可表示为:
m≡c+k mod n (其中n为基本字符个数)
该程序既可用于加密又可用于解密。只要执行:
java Caesar 明文(要加密的字符串) 密钥(移动的位数)
在密钥前面加上负号,将运行解密。
加密:
解密:
加密Helloworld
解密Helloworld
2.Java对称加密-DES算法
本实例给出Java中创建对称密钥的步骤,并通过对象序列化方式保存在文件中。
运行java Skey_DES,在当前目录下将生成文件key1.dat,其中包含的密钥可以用于使用Triple-DES算法的加密和解密。
先创建文件输出流对象,在其参数中指定文件名,如keykb1.dat。然后执行文件输出流的write( )方法将第2步中得到的字节数组中的内容写入文件。
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]+",");
}
}
}
输入java Skey_kb 运行程序,在程序的当前目录中将产生文件名为keykb1.dat的文件,屏幕输出如下:
此即程序中创建的密钥的编码内容,如果用文本编辑器打开keykb1.dat,看到的不是上面的数字而是类似下面的字符:
棄2 ?&驊 馤禖??僪*
3.Java非对称加密-RSA算法
输入java Skey_RSA运行程序,当前目录下将生成两个文件:Skey_RSA_pub.dat和Skey_RSA_priv.dat,前者保存着公钥,后者保存着私钥。
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
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( );
}
}
程序最后将密文c打印出来,并以字符串形式保存在文件中。
运行程序
输入java Enc_RSA运行程序,得到如下结果:
中显示了公钥中的参数以及加密的结果c,这些都是很大的整数,n和c多达上百位。程序运行后密文c以字符串形式保存在文件Enc_RSA.dat中。
RSA算法解密的结果m是一个很大的整数,为了计算出其对应的字符串的值,先使用BigInteger类的toByteArray( )方法得到代表该整型数的字节数组,然后将数组中每个元素转换为字符,组成字符串。
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
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]);
}
}
}
运行程序输入java Dec_RSA运行程序,得到如下结果:
其中显示了私钥中的参数以及解密的结果,其中整型的明文转换后显示出字符串“Hello World!”。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 15/15 | 1/1 | 23/26 | |
第二周 | 208/240 | 2/2 | 35/38 | |
第三周 | 376/584 | 3/3 | 32/38 | |
第四周 | 823/1407 | 4/4 | 28/30 | |
第五周 | 986/2393 | 5/5 | 21/26 | |
第六周 | 1258/3651 | 6/6 | 26/25 | |
第七周 | 575/4226 | 7/7 | 14/16 | |
第八周 | 390/4616 | 8/8 | 15/18 | |
第十周 | 363/6192 | 10/10 | 17/20 | |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。 | ||||
耗时估计的公式 | ||||
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。 |
-
计划学习时间:20小时
-
实际学习时间:17小时