http客户端程序已集成在java语言中,可以通过urlconnection类调用。遗憾的是,由于sun没有公布http客户程序的源码,它实现的细节仍是一个谜。本文根据http协议规范,用java.net.socket类实现一个http协议客户端程序。
1.socket类
了解tcp/ip协议集通信的读者知道,协议间的通信是通过socket完成的。在java.net包中,socket类就是对socket的具体实现。它通过连接到主机后,返回一个i/o流,实现协议间的信息交换。
2 . http协议
http协议同其它tcp/ip协议集中的协议一样,是遵循客户/服务器模型工作的。客户端发往服务端的信息格式如下:
请求方法 url http协议的版本号
提交的元信息
**空行**
实体
请求方法是对这次连接工作的说明,目前http协议已经发展到1.1版,它包括get、head、post、delete、options、trace、put七种。元信息是关于当前请求的信息。通过分析元信息,可以检查实体数据是否完整,接收过程是否出错,类型是否匹配等。元信息的引入使http协议通信更加稳妥可靠。实体是请求的具体内容。
将上述报文发往web服务器,如果成功,应答格式如下:
http协议的版本号 应答状态码 应答状态码说明
接收的元信息
**空行**
实体
以上报文发向客户端,并且接收成功,彼此间关闭连接,完成一次握手。
下面用最常用的get方法,来说明具体的报文应用
get http://www.youhost.com http/1.0
accept: www/source; text/html; image/gif; image/jpeg; */*
user_agent: myagent
**空行**
这个报文是向www.youhost.com主机请求一个缺省html文档。客户端http协议版本号是1.0版,元信息包括可接收的文件格式,用户代理,每一段之间用回车换行符分隔,最后以一个空行结束。发向服务器后,如果执行过程正常,服务器返回以下代码:
http/1.1 200 ok
date: tue, 14 sep 1999 02:19:57 gmt
server: apache/1.2.6
connection: close
content-type: text/html
**空行**
<html><head>...</head><body>...</body></html>
http/1.1表示这个http服务器是1.1版,200是服务器对客户请求的应答状态码,ok是对应答状态码的解释,之后是这个文档的元信息和文档正文。(相关应答状态码和元信息的解释请参阅.net.net标准草案:rfc2616)。
3. http客户端程序:
import java.net.*;
import java.io.*;
import java.util.properties;
import java.util.enumeration;
public class http {
protected socket client;
protected bufferedoutputstream sender;
protected bufferedinputstream receiver;
protected bytearrayinputstream bytestream;
protected url target;
private int responsecode=-1;
private string responsemessage="";
private string serverversion="";
private properties header = new properties();
public http() { }
public http(string url) {
get(url) ;
}
/* get方法根据url,会请求文件、数据库查询结果、程序运行结果等多种内容 */
public void get(string url) {
try {
checkhttp(url);
openserver(target.gethost(),target.getport() );
string cmd = "get "+ geturlformat(target) +" http/1.0 "
+ getbaseheads()+" ";
sendmessage(cmd);
receivemessage();
}catch(protocolexception p) {
p.printstacktrace();
return;
}catch(unknownhostexception e) {
e.printstacktrace();
return;
}catch(ioexception i)
i.printstacktrace();
return;
}
}
/*
* head方法只请求url的元信息,不包括url本身。若怀疑本机和服务器上的
* 文件相同,用这个方法检查最快捷有效。
*/
public void head(string url) {
try {
checkhttp(url);
openserver(target.gethost(),target.getport() );
string cmd = "head "+geturlformat(target)+" http/1.0 "
+getbaseheads()+" ";
sendmessage(cmd);
receivemessage();
}catch(protocolexception p) {
p.printstacktrace();
return;
}catch(unknownhostexception e) {
e.printstacktrace();
return;
}catch(ioexception i)
i.printstacktrace();
return;
}
}
/*
* post方法是向服务器传送数据,以便服务器做出相应的处理。例如网页上常用的
* 提交表格。
*/
public void post(string url,string content) {
try {
checkhttp(url);
openserver(target.gethost(),target.getport() );
string cmd = "post "+ geturlformat(target) +"
http/1.0 "+getbaseheads();
cmd += "content-type: application/x-www-form-urlencoded ";
cmd += "content-length: " + content.length() + " ";
cmd += content+" ";
sendmessage(cmd);
receivemessage();
}catch(protocolexception p) {
p.printstacktrace();
return;
}catch(unknownhostexception e) {
e.printstacktrace();
return;
}catch(ioexception i)
i.printstacktrace();
return;
}
}
protected void checkhttp(string url) throws protocolexception {
try {
url target = new url(url);
if(target==null !target.getprotocol().touppercase().equals("http") )
throw new protocolexception("这不是http协议");
this.target = target;
}catch(malformedurlexception m) {
throw new protocolexception("协议格式错误");
}
}
/*
* 与web服务器连接。若找不到web服务器,.netaddress会引发unknownhostexception
* 异常。若socket连接失败,会引发ioexception异常。
*/
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器