20155321 2016-2017-2 《Java程序设计》第十周学习总结
教材学习内容总结
-
网络概览
-
局域网和广域网:局域网通常限定在一个有效的地理区域之内,广域网由许多局域网组成。最大的网络是互联网
-
协议:两台计算机用来通信的“语言”
-
应用层上的常见的协议:HTTP(比较流行),FTP,telnet;传输层上常见的协议:TCP,UDP;高层直接使用底层的协议
-
Java提供类来封装应用层协议
-
网络使用地址系统来区分计算机,每台计算机都分配了一个唯一的IP地址,但IP地址并非网络地址系统中最小的单位,端口才是最小的单位
-
-
超文本传输协议(HTTP)
-
HTTP是允许Web服务器和浏览器之间通过互联网发送和接收数据的协议,是一种请求和响应协议。客户端请求一个文件,而服务器则响应该请求
-
HTTP请求
- 由三部分组成:方法——统一资源标识符——协议/版本,请求头(包含关于客户端环境和请求实体的有用信息,每个头部都用一个回车序列隔开),请求实体(请求头与请求实体之间有一个空行隔开)
-
HTTP相应
- 由三部分组成:协议-状态码-说明,响应头,响应实体
-
java.net.URL
- URL是互联网资源唯一的地址,由四部分组成:获取资源的协议——IP地址——端口号——指定到URL的路径
- 默认情况下,HTTP使用端口80
- HTTP是URL最常用却并非唯一的协议
- Java中,一个URL通过一个java.net.URL对象表示,可通过调用URL类的构造方法来构建一个URL
- 解析URL(在教材学习过程中)
- 读取Web资源(在教材学习过程中)
- 使用URL只能读取一个Web资源,要向服务器写内容需要用java.net.URL.Connection对象
-
java.net.URLConnection
- URLConnection表示到远程机器的一次连接,使用它读取资源并写到一台远程机器中
- 无法用new关键字创建此实例,但可以在一个URL对象上调用openConnection方法
- URLConnection有doInput(默认值为true)和doOutput(默认值为false)两个布尔型字段;可用setDoInput和setDoOutput方法来设置这两个值
- 读Web资源
- 写到一个Web服务器
-
java.net.Socket
- 套接字是一个网络连接的端点,它是的应用程序能够读取或者向网络写入信息。要从一个应用程程序向另一个应用程序发送一条信息需要知道另一个应用程序的IP地址以及套接字的端口号
- Java中用java.net.Socket对象来表示一个套接字
- 发送字节流需调用Socket类的getOutputStream方法来获取一个java.io.OutputStream对象;接收字节流需调用Socket类的getInputStream方法,它返回一个java.io.InputStream;要向远程应用程序发送文本需从返回的OutputStream对象构建一个java.io.PrintWriter对象
-
java.net.ServerSocket
- SeverSocket是服务器套接字的一个实现。一旦服务器套接字获得了一个连接请求,它会创建一个Socket实例以处理和客户端的通信
- 若有一个SeverSocket,可以让它在服务器套接字监听的端口上等待对绑定地址的一个入向连接请求,可通过调用SeverSocket类的accept方法来做到这一点。只有当有一个连接请求的时候,accept方法才会返回Socket类的一个实例
-
一个Web服务器应用程序
- HTTPServer类
- Response类
- Request类
教材代码合成如下:
-
import jdk.nashorn.internal.ir.RuntimeNode;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpServer {
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
private boolean shutdown = false;
public static void main(String[] args) {
HttpServer server = new HttpServer();
server.await();
}
public void await(){
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port,1, InetAddress.getByName("127.0.0.1"));
}catch (IOException e){
e.printStackTrace();
System.exit(1);
}
while(!shutdown){
Socket socket = null;
InputStream input = null;
OutputStream output = null;
try{
socket = serverSocket.accept();
input = socket.getInputStream();
output = socket.getOutputStream();
Request request = new Request(input);
request.parse();
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();
socket.close();
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
}catch (Exception e){
e.printStackTrace();
continue;
}
}
}
}
import java.io.IOException;
import java.io.InputStream;
public class Request {
private InputStream input;
private String uri;
public Request(InputStream input){
this.input = input;
}
public void parse(){
StringBuilder request = new StringBuilder(2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
}catch (IOException e){
e.printStackTrace();
i = -1;
}
for(int j = 0;j < i;j++){
request.append((char)buffer[j]);
}
System.out.print(request.toString());
uri = parseUri(request.toString());
}
private String parseUri(String requestString){
int index1 = requestString.indexOf(' ');
int index2;
if(index1 != -1){
index2 = requestString.indexOf(' ',index1+1);
if(index2 > index1){
return requestString.substring(index1 + 1,index2);
}
}
return null;
}
public String getUri(){
return uri;
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Response {
private static final int BUFFER_SIZE = 1024;
Request request;
OutputStream output;
public Response(OutputStream output){
this.output = output;
}
public void setRequest(Request request){
this.request = request;
}
public void sendStaticResource() throws IOException{
byte[] bytes = new byte[BUFFER_SIZE];
Path path = Paths.get(System.getProperty("user.dir"),"webroot",request.getUri());
if(Files.exists(path)){
try(InputStream inputStream = Files.newInputStream(path)) {
int ch = inputStream.read(bytes,0,BUFFER_SIZE);
while (ch != -1){
output.write(bytes,0,ch);
ch = inputStream.read(bytes,0,BUFFER_SIZE);
}
}catch (IOException e){
e.printStackTrace();
}
}else{
String errorMessage = "HTTP/1.1 404 File Not Found
"
+ "Content-Type:text/html
"
+ "Content-Length:23
" + "
"
+ "<h1>File Not Found</h1>";
output.write(errorMessage.getBytes());
}
}
}
运行结果如下图:
教材学习中的问题和解决过程
- 问题1:教材上此代码不知为何无法通过编译
import java.net.URL;
public class URLDemo1 {
public static void main(String[] args) {
URL url = new URL(
"http://www.yahoo.com:80/en/index.html?name=john#first"
);
System.out.println("protocol:"+url.getProtocol());
System.out.println("port:"+url.getPort());
System.out.println("host:"+url.getHost());
System.out.println("path:"+url.getPath());
System.out.println("file:"+url.getFile());
System.out.println("query:"+url.getQuery());
System.out.println("ref:"+url.getRef());
}
}
- 问题1解决方案:最后通过查找API与仔细对比才发现是自己忘记在主函数旁白抛出异常,应在
public static void main(String[] args)
后面加上throws Exception
代码调试中的问题和解决过程
- 问题1:以下代码是按照课本打的,但是不知道为什么运行不了,错误提示信息为
java.net.SocketException: Connection reset
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class URLDemo2 {
public static void main(String[] args) {
try {
URL url = new URL("http://www.google.com/");
InputStream inputStream = url.openStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream)
);
String line = bufferedReader.readLine();
while(line!=null){
System.out.println(line);
line = bufferedReader.readLine();
}
bufferedReader.close();
}
catch (MalformedURLException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
}
}
- 问题1解决方案:暂时未解决
代码托管
上周考试错题总结
目前尚不知考题的具体答案与解析
结对及互评
点评过的同学博客和代码
其他(感悟、思考等,可选)
我觉得本周学习有跨学科的感觉,有些知识是在计算机网络这门课程中提到的,比如局域网、广域网、物理层、传输层、应用层、协议这些概念,目前基本概念还是能理解一些,但是仍然不知道要如何使用这些元知识,希望之后的学习更偏向于这方面
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 1/ | 20/20 | 对IDEA、git、JDK、JVM有了更多的了解,面对学习过程中遇到的困难学会自己主动地寻找办法去解决 | |
第二周 | 1/2 | 18/38 | 掌握了Java中的基本运算符和基本语句 | |
第三周 | 1/3 | 22/60 | 对面向对象、封装、构造函数等重要知识点有了初步理解,学会自主学习,遇到困难的时候从多方面寻找资料以求答案 | |
第四周 | 1/4 | 22/60 | 对继承和多态了一定程度的理解,并学会使用多态来提高代码的复用性 | |
第五周 | 706/2639 | 1/5 | 25/85 | 对异常以及集合框架的学习 |
第六周 | 735/3194 | 1/6 | 28/113 | 对IO流,多线程以及并行API的学习 |
第七周 | 428/3474 | 1/7 | 18/131 | 对Date的学习 |
第八周 | 351/3825 | 1/8 | 20/151 | 对日志API以及规则表达式的学习 |
第九周 | 1172/ 4997 | 1/9 | 22/173 | JDBC与数据库 |
第十周 | 416/5413 | 1/10 | 20/193 | 网络编程 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:18小时
-
实际学习时间:20小时
-
改进情况:多实践
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)