应用协议的实现
概概 述述
应用协议规范应用协议规范
SMTPSMTP通信协议通信协议
POP3POP3通信协议通信协议
FTPFTP协议协议
HTTPHTTP协议协议
统一资源定位器统一资源定位器URLURL类与类与HTTPHTTP协议协议
1
概 述
TCP/IP模型将OSI参考模型中的会话层和表示层的功能合
并到应用层。针对各种各样的网络应用,应用层引入了许
多协议,称为应用协议。
应用协议服务于各种应用功能:
收发电子邮件(E-mail)
上传和下载文件
浏览网站
登录远程服务器
应用协议分为两种传输协议:
UDP传输协议
TCP协议传输协议
本章重点讨论基于底层TCP和UDP协议套接字上的网络通
信的编程实现。
2
基于TCP协议传输协议的
应用层协议
基于UDP传输协议的
应用层协议
RFC
(Request For Comment )文档介绍
应用协议规范
3
基于TCP协议的应用层协议
1.TELNET,虚拟终端协议
2.FTP(File Transfer Protocol) ,文件传输协议
3.POP3(Post Office Protocol-Version 3) ,邮局协议-版本3
4.IMAP4(Internet Message Access Pprotocol-Version 4) ,
Internet消息访问协议-版本4
5.SMTP(Simple Mail Transfer Protocol) ,简单邮件传送协议
6.HTTP(Hypertext Transfer Protocol) ,超文本传输协议
7.HTTPS(Secure Hypertext Transfer Protocol) ,安全超文本传输
协议
4
表5-1 常见的应用层协议使用的TCP协议端口
5
基于UDP协议的应用层协议
1.SNMP
(Simple Network Management Protocol)
简单网络管理协议
2.DNS
(Domain Name Server)
域名解析协议
6
RFC(Request For Comment)
文档介绍
RFC
编号 协 议
768 用户数据报协议(UDP)
783 日常文件传输协议(TFTP)
791 Internet协议(IP)
792
Internet控制消息协议
(ICMP)
793 传输控制协议(TCP协议)
821
邮件传输协议(SMTP,最新
更新RFC5336)
RFC
编号 协 议
854 Telnet协议(TELNET)
959 文件传输协议(FTP,最新更新RFC3659)
1157 简单网络管理协议(SNMP)
1939 邮局协议-版本3(POP3,最新更新RFC5034)
1945 超级文本传输协议-版本 ()
2060 Internet消息访问协议-版本4(IMAP4)
2068
超文本传输协议-版本(,为
RFC1945的更新版,第二次更新RFC2616) 7
SMTP通信协议
8
1 SMTP介绍
当用户需要发送邮件时,SMTP客户程序使用一组简单的命
令与SMTP服务器关联,并通过它把邮件发送出去,而后结
束连接和发送。
1.SMTP请求/响应协议命令与格式
命令和响应都是基于ASCII文本,命令以CRLF符结束为一条命令格
式,其中CR为“\r”表示回车,LF为“\n”表示换行,SP表示空
格。
应答码:响应包括一个表示返回状态的三位数字代码。
2.SMTP协议的传输模型
3.SMTP协议发送邮件过程
9
1.SMTP请求/响应协议命令与格式
命 令 格 式 描 述
HELO/EHLO HELO<SP> <domain> <CRLF> 指明邮件发送者的主机域名
MAIL FROM
MAIL <SP> FROM:<reverse-path>
<CRLF> 指明邮件发送者的信箱名称
RCPT TO
RCPT <SP> TO:<forward-path>
<CRLF> 指明邮件接收者的信箱名称
DATA DATA <CRLF> 表示发送邮件内容(包括信头和信体)
QUIT QUIT <CRLF> 终止邮件会话
HELP HELP [<SP> <string><CRLF>] 查询服务器支持什么命令
RSET RSET <CRLF> 重设邮件连接
NOOP NOOP <CRLF> 无操作,服务器应响应OK
TURN TURN <CRLF> 接收端和发送端交换角色
10
SMTP的应答码
应 答 码 描 述
214 帮助信息
220 服务就绪
221 服务关闭
250 邮件操作完成
354 开始输入邮件内容,以“.”结束
421 服务未就绪,关闭传输通道
501 命令参数格式错误
502 命令不支持
503 错误的命令序列
504 命令参数不支持
11
2.SMTP协议的传输模型
图 SMTP协议传输模型
12
3.SMTP协议发送邮件过程
SMTP协议发送一封电子邮件从SMTP客户端传输到SMTP服务器,只用表5-3
所示中前5个命令即可。客户端与邮件服务器连接和发送邮件过程如下:
① 客户端A与邮件服务器B建立TCP/IP协议连接;邮件服务器B响应,返回应
答码220,表示就绪。
② 客户端A发送“HELO”命令以标识发件人自己的身份,即发件人主机域名,
邮件服务器B响应,返回应答码250,表明可以接收。
③ 客户端A发送“MAIL FROM”命令,以标识该电子邮件的发件人邮件地址,
服务器B返回应答码250及OK作为响应,表明准备接收邮件。
④ 客户端A发送“RCPT TO”命令,以标识该电子邮件的接收人邮件地址,服务
器B返回应答码250及OK作为响应。
⑤ 协商结束,发送邮件,客户端A发送命令“DATA”,服务器B返回应答码354
,可发送内容,并说明发送“.”表示结束。客户端A发送邮件内容。
⑥ 客户端A发送“.”表示结束输入内容,服务器B返回应答码250,表示此操
作完毕。
⑦ 结束此次发送,客户端A发送命令“QUIT”退出。服务器B返回应答码221,
表示服务器B关闭。
13
2 SMTP客户端
——Java应用程序
public class sendSMTPMail {
/**
*<br>方法说明:主方法
*<br>输入参数:1 服务器ip;2 对方邮件地址
*<br>返回类型:
*/
public static void main(String[] arges) {
if(!=2){
("use java sendSMTPMail hostname | mail to");
return;
}
sendSMTPMail t = new sendSMTPMail();
(arges[0], arges[1]);
}
14
public void sendMail(String mailServer, String recipient) {
try {
//有Socket打开25端口
Socket s = new Socket(mailServer, 25);
//缓存输入和输出
BufferedReader in = new BufferedReader
(new InputStreamReader(()));
BufferedWriter out = new BufferedWriter
(new OutputStreamWriter(()));
//发出“HELO”命令,表示对服务器的问候
send( out, "HELO aaa");
//告诉服务器我的邮件地址,有些服务器要校验这个地址
send( out, "MAIL FROM: <06281040@>");
//使用“RCPT TO”命令告诉服务器解释邮件的邮件地址
send( out, "RCPT TO: " + recipient);
//发送一个“DATA”表示下面将是邮件主体
send( out, "DATA");
15
//使用Subject命令标注邮件主题
String str1 = "Subject: zao shang hao";
send( out, str1);
//使用“From”标注邮件的来源
send(out, "From: 06281040@");
send (out, "\n");
//邮件主体
send(out, "呵呵");
send(out, "\n.\n");
//发送“QUIT”端口邮件的通讯
send( out, "QUIT");
();
}
catch (Exception e) {
();
}
}
16
public void send(BufferedWriter out, String s) {
try {
(s + "\n");
();
(s);
}
catch (Exception e) {
();
}
}
17
POP3通信协议
18
1 POP3介绍
POP3邮件服务器接收并保存邮件
POP3分客户端程序和服务器
POP3也是命令请求/响应协议
在TCP协议110号端口监听连接请求。
1、合法身份登录,即客户端发送命令“USER”和“PASS”。服
务器应答返回“+OK”,表示用户登录成功,此时由认可状态转
换为处理状态。
2、客户端发送一系列POP3命令,服务器应答 “+OK”成功和“
-ERR”失败两种。转换为处理状态 。
POP3协议中有三种状态:认可、处理和更新状态。
19
POP3的主要命令、格式和描述
命令 格 式 状态 描 述
USER
USER <SP> <username>
<CRLF> 认可
用户名,此命令与下面的PASS命令若成功,将
导致状态转换
PASS PASS <SP> <password> <CRLF> 认可
用户密码,命令若成功,状态由“认可”转换为
“处理”
STAT STAT <CRLF> 处理
请求服务器发回关于邮箱的统计资料,如邮件总
数和总字节数;信箱状态
RETR RETR<SP><msg><CRLF> 处理 返回由参数标识的邮件的全部文本
LIST LIST <SP>[msg]<CRLF> 处理 返回邮件数量和每个邮件的大小
QUIT QUIT <CRLF> 更新 退出并把做过DELE标记的邮件删掉
DELE DELE <SP><msg><CRLF> 处理
服务器将由参数标识的邮件标记为删除,由
QUIT命令执行
RSET RSET <CRLF> 处理
服务器将重置所有标记为删除的邮件,用于撤销
DELE命令
UIDL UIDL <SP>[msg]<CRLF> 处理
返回邮件的唯一标识符,POP3会话的每个标识符
都将是唯一的
TOP TOP <SP><msg n><CRLF> 处理
服务器将返回由参数标识的邮件前n行内容,n必
须是正整数
NOOP NOOP <CRLF> 处理 服务器返回一个肯定的响应
20
常用命令
命令都是基于ASCII文本的,最常用的是
USER、PASS、STAT、RETR、DELE和
QUIT
21
class POP3Demo {
private static String POP3Server = "";
private static String USERNAME = "username";//实际应用中改成真实的用户名
private static String PASSWORD = "password";//实际应用中改成真实的密码
public static void main(String[] args) {
int POP3Port = 110;
Socket client = null;
try {
// 向POP3服务程序建立一个套接字连接。
client = new Socket(, POP3Port);
// 创建一个BufferedReader对象,以便从套接字读取输出。
InputStream is = ();
BufferedReader sockin = new BufferedReader(new InputStreamReader(is));
// 创建一个PrintWriter对象,以便向套接字写入内容。
OutputStream os = ();
PrintWriter sockout = new PrintWriter(os, true);
// 显示同SMTP服务程序的握手过程。
("S:" + ());
("user " + );
("S:" + ());
("pass " + );
("S:" + ());
("stat"); 22
String temp[] = ().split(" ");
int count = (temp[1]);//得到信箱中共有多少封邮件
for (int i = 1; i < count + 1; i++) {//依次打印出邮件的内容
("retr " + i);
("以下为第" + i + "封邮件的内容");
while (true) {
String reply = ();
(reply);
if (().equals(".")) {
break;
}
}
}
} catch (IOException e) {
(());
} finally {
try {
if (client != null) {
();
}
} catch (IOException e) {}
}
}
}
23
5 FTP协议
24
25
1 FTP协议体系结构
FTP客户端分为三个层次:
用户接口UI(User Interface)
用户协议执行器PI(The User Protocol Interpreter)
用户数据传输进程DTP(The User Data Transfer Process);
FTP服务器分为两个层次:
服务器协议执行器PI(The Server Protocol Interpreter)
服务器数据传输进程DTP(The Server Data Transfer Process)。
26
FTP客户端与服务器传输模型
27
FTP协议使用两个层次的连接:
第一个层次是由两个PI形成的控制连接
是由用户PI直接建立的专用于发送FTP命令的连接,向服务器PI提出查看或
下载文件的请求,连接遵循Telnet协议,称控制连接;
第二个层次是由DTP形成的数据连接
由用户PI发出数据传输命令,服务器PI响应,并控制服务器DTP而建立的专
用于传递数据的连接,称数据连接,它响应用户端的请求把指定的文件传送
到客户端计算机中。
一旦两个DTP之间数据连接建好,就开始传送数据。
这两个层次的连接,也是两条单独的基于双工通信链路的TCP协议连接。
28
FTP的主要命令、格式和描述
1、访问控制命令
命 令 格 式 描 述
USER USER <SP> <username> <CRLF> 系统登录的用户名
PASS PASS <SP> <password> <CRLF> 系统登录的用户密码
CWD CWD <SP> <pathname> <CRLF> 改变服务器上的工作目录,即切换目录
CDUP CDUP <CRLF> 切换到上一层目录
QUIT QUIT <CRLF> 从FTP服务器上退出登录
29
FTP的主要命令、格式和描述
2、传输参数命令:
命 令 格 式 描 述
PORT PORT <SP> <host-port> <CRLF> IP地址和两字节的端口ID(主动模式)
TYPE TYPE <SP> <type-code> <CRLF> 数据类型(A=ASCII,E=EBCDIC,I=binary)
STRU STRU<SP> <structure-code> <CRLF> 数据结构(F=文件,R=记录,P=页面)
MODE MODE <SP> <mode-code> <CRLF> 传输模式(S=流模式,B=块模式,C=压缩模式)
PASV PASV <CRLF> 请求服务器等待数据连接(被动模式)
30
FTP的主要命令、格式和描述
3、FTP服务命令
命 令 格 式 描 述
RETR RETR <SP> <pathname> <CRLF> 从服务器中获得(找回)文件
STOR STOR <SP> <pathname> <CRLF> 向服务器中发送文件
STOU STOU <CRLF> 存储文件到服务器名称上
DELE DELE <SP> <pathname> <CRLF> 删除服务器上的指定文件
LIST LIST [<SP> <pathname>] <CRLF> 如果是文件名列出文件信息,如果是目录则列
出文件列表
RMD RMD <SP> <pathname> <CRLF> 删除指定文件夹
MKD MKD<SP> <pathname> <CRLF> 在服务器上建立指定目录
PWD PWD <CRLF> 显示(打印)当前工作目录
HELP HELP [<SP> <string>] <CRLF> 返回指定命令信息
31
FTP的部分应答码
应 答 码 描 述
150 文件状态正常,准备打开数据连接
200 命令执行成功
220 服务就绪,可以执行新用户的请求。如
与服务器连接成功
221 服务关闭控制连接。如果适当,请注销
227 进入被动模式
230 用户登录成功,继续进行
250 目录切换成功,已完成
257 已创建文件夹
331 用户名正确,输入密码
应 答 码 描 述
350 请求的文件操作正在等待进一步的信息
421
服务不可用,正在关闭控制连接。如果服务
确定它必须关闭,将向任何命令发送这一应
答
425 无法打开数据连接
450 请求的文件操作未执行
452 未执行请求的操作。系统存储空间不够
500 语法错误,命令无法识别
501 在参数中有语法错误
502 命令未实现
530 未登录
550 未执行请求的操作。文件不可用
32
.2 FTP工作模式(1)
FTP协议有两种工作模式:它们使用的端口不同,工作流程也不同。
Active模式:主动方式(PORT)
命令通道建立:客户端PI使用随机端口号N呼叫服务器PI的21端口(默认)
发送连接请求,服务器PI接收连接,建立一条控制连接,客户端PI发送用
户名和密码进行身份认证,确认后可发送FTP的命令。N端口要求N>1024。
数据连接通道建立:由命令通道客户端PI用PORT命令告知服务器PI,客
户端的“IP地址和已打开M端口,可连接”;服务器PI接到命令后,利用
20端口(默认)向客户端的M端口主动发送连接请求,服务器DTP与客户
端DTP建立一条数据链路来传送数据,称为主动模式 。 M端口在1025~
65535 之间,随机产生。
33
.2 FTP工作模式(2)
Passive模式:被动方式(PASV)
命令通道建立:同主动方式;
数据连接通道建立:通过命令通道客户端PI发送PASV命令,告诉服务器
要采用被动模式建立连接。当服务器PI接收命令后,服务器就会自动监听
端口M1被动等待连接,并利用命令通道告诉客户端PI“M1端口,可连接”
,客户端在接到此信息后,就会自动选择一个端口M2,与服务器DTP的
M1端口建立数据连接通道。对服务器来说数据连接通道DTP建立的过程
中,是被动等待连接,称为被动模式。 M1和M2端口在1025~65535中随
机产生。
34
3 服务器端FTP程序
35
关键命令
1.主动模式PORT(PORT)命令
2.被动模式PASV(PASSIVE)命令
3.文件下载RETR(RETEIEVE)和文件上传
STOR(STORE)命令
4.文件和目录列表LIST (LIST)命令
36
HTTP协议
37
1 HTTP协议概述
HTTP协议是一种灵活和迅速的应用于分布式、协作、超媒
体信息系统所需的应用层协议。这是一个通用、无状态、
面向对象的协议,通过扩展它的请求方法(命令)可用于
多种任务。
HTTP客户以Web浏览器作为客户工具通过HTTP协议向
HTTP服务器请求超文本文件,而超文本文件中包含着超链
接。
HTTP服务器使得Internet成为超文本文件的集合。
38
39
40
一个典型的<form>
<form method="post" name="loginForm"
action=“/login“>
用户名:
<input name="username"><br>
密 码:
<input name="password"
type="password">
<br>
<input type="submit" value="提交">
</form>
浏览器与服务器交互
Request
Response
一个典型的Http请求
POST
Host:
Accept:*/*
Pragma: no-cache
Cache-Control: no-cache
Referer:
User-Agent:Mozilla/[en](Win95;I;Nav)
Username=yuannan&password=111111
HTTP请求剖析
POST HTTP/
通过POST方法获得指定URL下的文件。
除了POST方法以外,还有GET,DEL,HEAD等等
HTTP请求剖析
Host:
Host:指定请求资源的Intenet主机和端口号,必须
表示请求url的原始服务器或网关的位置。HTTP/
请求必须包含主机头域,否则系统会以400状态码返
回。
HTTP请求剖析
username=yuannan&password=111111
POST到服务器中的数据。
HTTP请求剖析
User-Agent: Mozilla/[en](Win95;I;Nav)
User-Agent头域的内容包含发出请求的用户信息。
典型的HTTP响应
HTTP响应剖析
HTTP/ 200 OK
协议版本号,状态号
HTTP响应剖析
Server: Apache/(Unix)
服务器的名称,版本,以及服务器所在的操作系统
名称
HTTP响应剖析
Content-type: text/html
相应的内容的类型,html文本。
HTTP响应剖析
Last-modified: Tue,17 Apr 2001 06:46:28
GMT
Etag: "a030f020ac7c01:1e9f "
Last-modified文件的最后修改时间,而Etag则是以
及文件内容的生成的一个字符序列。通常用于实现客
户端缓存,降低服务器压力。当客户端发现请求并没
有被修改的话则直接使用本地的缓存。
HTTP响应剖析
Content-length: 39725426
响应内容的长度,单位为Byte。
HTTP响应剖析
观察HTTP协议的两个工具
HttpWatch, IE插件
Ethereal, 抓包工具
请求头格式
a) 通用头(general-header):
Cache-Control:客户端希望服务端如何缓存自己的请求数据,如
"Cache-Control: no-cache",
"Cache-Control: max-age=0";
Connection:客户端是否希望与服务端之间保持长连接,如
"Connection: close",
"Connection: keep-alive";
Date:只有当请求方法为POST或PUT方法时客户端才可能会有些字段;
Pragma:包含了客户端一些特殊请求信息,如
"Pragma: no-cache" 客户端希望代理或应用服务器不应缓存与该请求相关的结果数
据;
Via:一般用在代理网关向应用服务器发送的请求头中,表明该来自客户端的请
求经过了网关代理,格式为:"Via: 请求协议版本 网关标识 [其它信息] ",
如 :" Via: :80 (squid)"
57
请求头格式
58
请求头格式
b) 请求头(request-header):
Accept-Encoding:客户端所能识别的编码压缩格式,
如:“Accept-Encoding: gzip, deflate”;
If- Modified-Since:该字段与客户端缓存相关,客户端所访问的URL自该指定日期以来在
服务端是否被修改过,如果修改过则服务端返回新的修改后的信息,如果未修改过则服务
器返回304表明此请求所指URL未曾修改过,
如:“If-Modified-Since: Fri, 2 Sep 2006 19:37:36 GMT”;
If-None-Match:该字段与客户端缓存相关,客户端发送URL请求的同时发送该字段及标
识,如果服务端的标识与客户端的标识一致,则返回304表明此URL未修改过,如果不一
致则服务端返回完整的数据信息,
如:“If-None-Match: 0f0a893aad8c61:253, 0f0a893aad8c61:252, 0f0a893aad8c61:251”;
Cookie:为扩展字段,存储于客户端,向同一域名的服务端发送属于该域的cookie,
如:“Cookie: MailUserName=whouse”;
59
请求头格式
60
响应格式
a) 通用头(general-header):
Cache- Control:服务端要求中间代理及客户端如何缓存自己响应的数据,
如“Cache-Control: no-cache”,
如:“Cache-Control: private” 不希望被缓存,
“Cache-Control: public” 可以被缓存;
Connection:服务端是否希望与客户端之间保持长连接,
如“Connection: close”, “Connection: keep-alive”;
Date:只有当请求方法为POST或PUT方法时客户端才可能会有些字段;
Pragma:包含了服务端一些特殊响应信息,
如 “Pragma: no-cache” 服务端希望代理或客户端不应缓存结果数据;
Transfer-Encoding:服务端向客户端传输数据所采用的传输模式(仅在中出现),
如:“Transfer-Encoding: chunked”,
注:该字段的优先级要高于“Content-Length” 字段的优先级;
61
响应格式
62
响应格式
c)实体头(entity-header): (此类头存在时要求有数据体)
Content-Encoding:服务端所响应数据的编码格式,
如:“Content-Encoding: gzip”;
Content-Length:服务端所返回数据的数据体部分的内容长度,
如:“ Content-Length: 24”;
Content-Type:服务端所返回的数据体的内容类型,
如:“Content-Type: text/html; charset=gb2312” ;
Set-Cookie:服务端返回给客户端的cookie数据,
如:“ Set-Cookie: _SessionId=icnh2ku2dqlmkciyobgvzl55;
path=/”
63
服务器返回状态码
1xx:表明服务端接收了客户端请求,客户端继续发送请求;
2xx:客户端发送的请求被服务端成功接收并成功进行了处理;
3xx:服务端给客户端返回用于重定向的信息;
4xx:客户端的请求有非法内容;
5xx:服务端未能正常处理客户端的请求而出现意外错误。
举例:
“100” ; 服务端希望客户端继续;
“200” ; 服务端成功接收并处理了客户端的请求;
“301” ; 客户端所请求的URL已经移走,需要客户端重定向到其它的URL;
“304” ; 客户端所请求的URL未发生变化;
“400” ; 客户端请求错误;
“403” ; 客户端请求被服务端所禁止;
“404” ; 客户端所请求的URL在服务端不存在;
“500” ; 服务端在处理客户端请求时出现异常;
“501” ; 服务端未实现客户端请求的方法或内容;
“502” ; 此为中间代理返回给客户端的出错信息,表明服务端返回给代理时出错;
“503” ; 服务端由于负载过高或其它错误而无法正常响应客户端请求;
“504” ; 此为中间代理返回给客户端的出错信息,表明代理连接服务端出现超时。
64
65
GET请求
GET
Host:
User-Agent: Mozilla/ (Windows; U; Windows NT ; zh-CN; rv:)
Gecko/20061010 Firefox/
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=,text/plain;q=,ima
ge/png,*/*;q=
Accept-Language: en-us,zh-cn;q=,zh;q=
Accept-Encoding: gzip,deflate
Accept-Charset: gb2312,utf-8;q=,*;q=
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: _SessionId=ey5drq45lsomio55hoydzc45
Cache-Control: max-age=0
66
POST请求
67
查看HTTP协议的执行过程
Telnet远程终端程序可以帮助我们查看HTTP
及其它协议的详细执行情况
Telnet是TCP/IP协议要求的基本应用程序(协议)
Windows系统自身携带了Telnet程序
进入Windows的命令窗口
程序->附件->命令提示符
运行->cmd
退出Windows的命令窗口
exit
输入telnet
窗口进入Telnet状态, 给出telnet命令提示符
68
查看HTTP协议的执行过程
微软的Telnet程序用起来不是很方便
Telnet程序有许许多多
Cygwin中的Telnet
为避免命令的重命, 将Cygwin中的程序改名为
该命令运行时需要动态连接库的支持
建议: 在硬盘上建立一个子目录(文件夹, telnetc), 在其中放入
和程序
在命令窗口中,将当前目录转到上述子目录
X: 转到某个盘
CD <子目录> 进入下一级子目录
CD .. 返回上一级目录
CD .. 返回到根目录
69
查看HTTP协议的执行过程
Telnet的常用命令
? 获取帮助
Quit 退出
Open <主机名/IP> <端口号>
open localhost 80
70
HTTP GET命令格式
HTTP GET命令格式
GET / HTTP/
host:localhost
两次回车
HTTP GET命令格式
GET / HTTP/
两次回车
浏览器隐藏了HTTP协议的执行细节
浏览器使HTTP协议的执行对用户是透明的 71
HTTP GET命令—获取默认主页
72
HTTP GET命令—获取默认主页
73
示例主页
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML
Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=gb2312">
<title>最简单的网页</title>
</head>
<body bgColor=silver>
<h3>这是一个最简单的网页</h3>
<p><font color=red>虽然这是一个非常简单的网页,
</font></p><hr><p>但是它依然体现了<br>HTML网页技术
中的一些深刻原理。</p>
</body>
</html>
74
BrowsingAPage/
HTTP GET命令—获取某个目录下的网页
75
HTTP GET命令—出错信息
76
HTTP GET命令执行示例
77
HTTP协议过程
服务器:包括HTML文件,一个HTTP驻留程序,即服务器程序,用于响应HTTP
客户请求。
浏览器:就是HTTP客户,向服务器发送请求,当浏览器中输入一个开始文件或
单击一个超链接时,浏览器就向服务器发送了HTTP请求,此请求被送往由IP地
址指定的URL。
程序接收到请求,在进行必要的操作后回送所要求的文件。之前,要建立HTTP
客户与HTTP服务器的连接,默认端口为80;之后,要关闭连接。
HTTP协议的内部操作过程分为4个过程:
建立连接、发送请求信息、发送响应信息和内容、关闭连接。 78
HTTP协议两个重点过程
1.HTTP客户发送请求信息
完整请求=请求行(通用信息头|请求头|实体头)CRLF[实体内容]
格式:Full-Request=Request-Line*(General-Header|Request-Header|Entity-Header)
CRLF[Entity-Body]
2.HTTP服务器发送响应信息和内容
响应消息=状态行(通用信息头|响应头|实体头)CRLF[实体内容]
格式:Full-Response=Status-Line*(General-Header|Response-Header|Entity-Header)
CRLF[Entity-Body]
请求方式
GET—客户端请求访问服务器上的一个文档;(网页)
POST—客户程序发送大量信息给服务器。通常包含大量HTML表单数据。
HEAD—客户端和服务器之间交流内部数据;服务器不会返回具体文档。对用户透明。
PUT —客户程序上传文档给服务器。
DELETE —客户程序删除服务器上的某个文档。 79
HTTP协议主要依靠的两个标准
HTML(Hypertext Markup Language) :
超文本标记语言,其文件称为HTML文档;是一个描述文
本数据语义值的简单标准。
MIME(Multipurpose Internet Mail Extensions ):
多功能Internet 邮件扩充服务,是对不同类型的数据(如
声音和文本)进行编码的一种方法。它将这些数据在一个
7位ASCII连接上传输。
Content-Type
80
极其简单的HTTP客户
//向:8080发送Http请求
Socket socket = new Socket("", "8080");
OutputStream os = ();
boolean autoflush = true;
PrintWriter out = new PrintWriter( (), autoflush );
BufferedReader in = new BufferedReader( new InputStreamReader(
() ));
// send an HTTP request to the web server
("GET / HTTP/");
("Host: localhost:8080");
("Connection: Close");
();
81
极其简单的HTTP客户
// read the response
boolean loop = true;
StringBuffer sb = new StringBuffer(8096);
while (loop) {
if ( () ) {
int i=0;
while (i!=-1) {
i = ();
((char) i);
}
loop = false;
}
().sleep(50);
}
// display the response to the out console
(());
();
82
简单的HTTP 服务器
public class SimpleHttpServer implements Runnable {
ServerSocket serverSocket; // 服务器Socket
/**
* 服务器监听端口, 默认为 80.
*/
public static int PORT = 80 ; // 标准HTTP端口
/**
* 开始服务器 Socket 线程.
*/
public SimpleHttpServer() {
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
( " 无法启动HTTP服务器: " + ());
}
if (serverSocket == null ) ( 1 ); // 无法开始服务器
new Thread( this ).start();
( " HTTP服务器正在运行,端口: " + PORT);
}
83
/**
* 运行服务器主线程, 监听客户端请求并返回响应.
*/
public void run() {
while ( true ) {
try {
Socket client = null ; // 客户Socket
int contentLength = 0 ; // 客户端发送的 HTTP 请求的主体的长度
client = (); // 客户机(这里是 IE 等浏览器)已经连接到当前服务器
if (client != null ) {
( " 连接到服务器的用户: " + client);
try {
// 第一阶段: 打开输入流
BufferedReader in = new BufferedReader( new InputStreamReader(
()));
( " 客户端发送的请求信息:\n=================== " );
// 读取第一行, 请求地址
String line = ();
(line);
String resource = (( ' / ' ),( ' / ' ) - 5 );
// 获得请求的资源的地址
resource = (resource, " UTF-8 " ); // 反编码 URL 地址
String method = new StringTokenizer(line).nextElement().toString(); // 获取
请求方法, GET 或者 POST 84
// 读取所有浏览器发送过来的请求参数头部信息
while ( (line = ()) != null ) {
(line);
// 读取 POST 等数据的内容长度
if (( " Content-Length " )) {
try {
contentLength = ((( ' : ' ) +
1 ).trim());
} catch (Exception e) {
();
}
}
if (( "" )) break ;
}
85
// 显示 POST 表单提交的内容, 这个内容位于请求的主体部分
if ( " POST " .equalsIgnoreCase(method) && contentLength > 0 ) {
( " 以下内容为 POST 方式提交的表单数据 " );
for ( int i = 0 ; i < contentLength; i ++ ) {
(( char )());
}
();
}
( " 请求信息结束\n=================== " );
( " 用户请求的资源是: " + resource);
( " 请求的类型是: " + method);
86
// GIF 图片就读取一个真实的图片数据并返回给客户端
if (( " .gif " )) {
fileService( " images/ " , client);
closeSocket(client);
continue ;
}
87
// 请求 JPG 格式就报错 404
if (( " .jpg " )) {
PrintWriter out = new PrintWriter((), true );
( " HTTP/ 404 Not found " ); // 返回应答消息,并结束应答
(); // 根据 HTTP 协议, 空行将结束头信息
();
closeSocket(client);
continue ;
} else {
// 用 writer 对客户端 socket 输出一段 HTML 代码
PrintWriter out = new PrintWriter((), true );
( " HTTP/ 200 OK " ); // 返回应答消息,并结束应答
( " Content-Type:text/html;charset=GBK " );
(); // 根据 HTTP 协议, 空行将结束头信息
( " <h1> Hello Http Server</h1> " );
( " 你好, 这是一个 Java HTTP 服务器 demo 应用.<br> " );
( " 您请求的路径是: " + resource + " <br> " );
( " 这是一个支持虚拟路径的图片:<img src=''><br> " +
" <a href=''>点击打开, 是个服务器虚拟路径的图片文件.</a> " );
( " <br>这是个会反馈 404 错误的的图片:<img src=''><br><a href=''>点击打开</a><br>
" );
( " <form method=post action='/'& gt;POST 表单 <input name=username value='用户'> < input
name=submit type=submit value=submit></form> " );
();
closeSocket(client);
}
} catch (Exception e) {
( " HTTP服务器错误: " + ());
}
}
// (client+"连接到HTTP服务器"); // 如果加入这一句,服务器响应速度会很慢
} catch (Exception e) {
( " HTTP服务器错误: " + ());
}
}
}
88
/**
* 读取一个文件的内容并返回给浏览器端.
* @param fileName 文件名
* @param socket 客户端 socket.
*/
void fileService(String fileName, Socket socket)
{
try
{
PrintStream out = new PrintStream((), true );
File fileToSend = new File(fileName);
if (() && ! ())
{
( " HTTP/ 200 OK " ); // 返回应答消息,并结束应答
( " Content-Type:application/binary " );
( " Content-Length: " + ()); // 返回内容字节数
(); // 根据 HTTP 协议, 空行将结束头信息
FileInputStream fis = new FileInputStream(fileToSend);
byte data[] = new byte [()];
(data);
(data);
();
();
}
}
catch (Exception e)
{
( " 传送文件时出错: " + ());
}
}
89
HTTP form
90
http request
POST / HTTP/
Host:
User-Agent: Mozilla/ (Windows; U; Windows NT ; en-US; rv:)
Gecko/20031007 Firebird/
Accept: text/xml,application/xml,application/xhtml+xml,text/
html;q=,text/plain;q=,video/x-mng,image/png,image/
jpeg,image/gif;q=,*/*;q=
Accept-Language: en-us,en;q=
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=,*;q=
Keep-Alive: 300
Connection: keep-alive
Cookie: CP=null*
Content-Type: multipart/form-data; boundary=---------------------------
41184676334
Content-Length: 438
-----------------------------41184676334
Content-Disposition: form-data; name="textfield"
Test
-----------------------------41184676334
Content-Disposition: form-data; name="file"; filename=""
Content-Type: text/plain
A small text file. Nothing to see here. Move along.
-----------------------------41184676334
Content-Disposition: form-data; name="Submit"
Submit
-----------------------------41184676334--
91
From HTTP to RPC
Remote procedure calls, or RPC, have been around for a
long time. The concept is simple: let's say you have a
function:
(Money amount);
The method is easy to understand and work with as part of
a program compiled and running on a single machine.
A RPC makes a method call on another machine.
// Local code
Money adjustment = new Money();
// Remote code
(adjustment); 92
Web service distributed computing
Concept CORBA Java Web
service
Interface
Description
IDL Java interface WSDL
RPC support ORBs RMI SOAP
Service registry CORBA
naming service
JNDI UDDI
Messaging
support
CORBA
Event/Notificati
on service
JMS ?
Transaction
support
CORBA
transaction
service
JTS, EJB ?
Security support CORBA
security
service
? ? 93