程 序 实 践 四
实验报告
姓 名 谭竹青 学 号
20073387
班 级 软件 0704 指 导 教 师 宋航
程 序 实 践 名 称 程序实践(网络应用程序设计)
程 序 实 践 内 容 计 算 机 强 化 训 练
开 设 学 期 2 0 0 9 - 2 0 1 0 第 一 学 期
开 设 时 间 第 1 3 周 — — 第 1 5 周
报 告 日 期 2009 年 12 月
评 定 成 绩
评 定 人 签 字
评 定 日 期
东北大学软件学院
程序实践四
1. 实践目的
写出本次实践的目的,要求简洁清楚。
(1) 通过查看 HTTP 协议的 RFC 文档,理解并掌握 HTTP 协议,加深理解 Web 的工
作原理;
(2) 掌握网络应用程序的开发方法;
(3) 掌握 Socket 机制的工作原理
(4) 能够用 Java 语言编写简单的 HTTP 1.0 客户端和服务器端的程序;
(5) 理解并掌握 HTTP 协议,线程和进程的区别,加深理解 Web 的工作原理;
(6) 掌握网络应用程序的开发方法;
(7) 掌握 Socket 机制的工作原理
(8) 能够用 Java 语言多线程机制,编写多线程服务器端的程序;
(9) 理解并掌握分布式系统的基本概念;
(10) 掌握分布式系统应用程序的开发方法;
(11) 掌握 RMI 工作原理;
(12) 能够用 Java 语言 RMI 机制,编写 RMI 程序;
2. 预习内容
写出本次实践过程中你所用到的知识;
(1) 复习 TCP/IP 协议栈;
(2) 复习并掌握 Web 技术相关知识和 HTTP 协议;
(3) 复习 Java 的网络编程相关知识;
(4) 复习网络应用程序的开发方法;
(5) 复习 Socket 机制;
(6) 复习 Java 多线程编程相关知识;
(7) 复习 Java 网络编程相关知识;
(8) 复习 RMI 机制;
2
3. 实践内容和实践过程
1. 编写简单的 HTTP 1.0 客户端程序,编写简单的 HTTP 1.0 服务器程序;
(1)实践内容
a. 对比 HTTP1.0 与 HTTP1.1 的差异
HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务
器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客
户也不记录过去的请求.HTTP 1.1支持持久连接,在一个TCP连接上可以传送多个HTTP请
求和响应,减少了建立和关闭连接的消耗和延迟。一个包含有许多图像的网页文件的多个
请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各
自的连接。HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,
但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够
区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。基于HTTP
1.1协议的客户机与服务器的信息交换过程。
b. 编写简单的 HTTP 1.0客户端程序
c. 编写简单的 HTTP 1.0服务器程序
(2)实现过程
Socket 和端口、IP 地址的关系:
实现 socket 编程的具体流程:
Server 端 socket client 端 socket
注意:
1 具体体现 Socket 的编程流程,注意区分 Java Socket 与其它 Socket 的区别;
2 在此实践中某些功能模块的实现流程;
3 最好利用 UML 的类图或结构化的程序流程图来描述程序的实现过程;
(3)关键技术
关键写出在完成各个功能时所使用的具体函数,但不要将全部程序代码粘贴;
Server 端主要代码:
Socket 生成:
final static int port = 8000;
ServerSocket welcomeSocket = new ServerSocket(port);
Socket 接受连接请求:
Socket httpSocket = welcomeSocket.accept();
接通时 System.out.println("已经与"+port+"端口建立连接.......");
Read 和 write 流 : BufferedReader inFromClient = new BufferedReader(new
InputStreamReader(httpSocket.getInputStream()) );
OutputStream os = httpSocket.getOutputStream();
处理请求,在 GET 后获取请求的文件名,如果该文件存在,服务端打开该文件并发
送 正 确 的 响 应 报 头 , 不 存 在 则 发 送 提 示 错 误 的 信 息 及 相 应 的 响 应 报 头 :
System.out.println("客户端的请求:"+clientSentence);
StringTokenizer s = new StringTokenizer(clientSentence);
String temp = s.nextToken();
String fName = null;
if(temp.equals("GET"))
{
String fileName = s.nextToken();
fName = fileName.substring(0);
fileName = "." + fileName;
FileInputStream fis = null;
开始
Socket 生成
连接接受请求
接通
关闭
开始
接通
关闭
Socket 生成
Connect
Read
Write
2
boolean fileExists = true;
try
{
fis = new FileInputStream(fileName);
}catch(FileNotFoundException e)
{
fileExists = false;
}
String status = null;
String conType = null;
String content = null;
String contentLength = "error";
if(fileExists)
{
status = "HTTP/1.0 200 OK " + CRLF;
conType = "Content-Type: " + ContentType(fileName) +
CRLF;
contentLength = "Content-Length :" + (new
Integer(fis.available()).toString()) + CRLF;
}
else
{
status = "HTTP/1.0 404 NOT Found " + CRLF;
conType = "text/html"+ CRLF;
content ="<HTML>"
+ "<HEAD><TITLE>404 Not Found</TITLE></HEAD>"
+ "<BODY>404 Not Found <br>"
+ fName+"<br><br><h1>ERROR</BODY></HTML>";
}
判断文件类型代码:
private static String ContentType(String fileName)
{
if(fileName.endsWith(".htm")||fileName.endsWith(".html"))
return "text/html";
else if(fileName.endsWith(".jpeg")||
fileName.endsWith(".jpg")||fileName.endsWith(".jpe"))
return "image/jpeg";
else if(fileName.endsWith(".gif"))
return "image/gif";
else return "fName";
}
Client 端主要代码:
3