分享
 
 
 

基于Java实现简单Http服务器之一

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

本文将详细介绍如何基于java语言实现一个简单的Http服务器,文中将主要介绍三个方面的内容:1)Http协议的基本知识、2)java.net.Socket类、3)java.net.ServerSocket类,读完本文后你可以把这个服务器用多线程的技术重新编写一个更好的服务器。

由于Web服务器使用Http协议通信的因此也把它叫做Http服务器,Http使用可靠的TCP连接来工作,它是面向连接的通信方式,这意味着客户端和服务器每次通信都建立自己的连接,它又是无状态的连接,当数据传输完毕后客户端和服务器端的连接立刻关闭,这样可以节省服务器的资源,当然如果需要传输大量的数据,你可以在Request的头设置Connection=keep-alive使得可以复用这一个连接通道。在HTTP协议中非常重要的两个概念就是:请求(Request)和(响应)这也是我在这里要讲述的如果你想了解Http更多的内容那么请参考http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf

一个Http请求包括三个重要的部分:

Method-URI-Protocol/Version

Request headers

Entity body

下面是一个Http请求的例子:

POST /servlet/default.jsp HTTP/1.1

Accept: text/plain; text/html

Accept-Language: en-gb

Connection: Keep-Alive

Host: localhost

Referer: http://localhost/ch8/SendDetails.htm

User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)

Content-Length: 33

Content-Type: application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

LastName=Franks&FirstName=Michael

其中第一行是Method-URI-Protocol/Version ,这是非常重要的部分,你需要从中读取客户端数据传输的方式,URI以及协议和版本,在这里分别是POST / servlet/default.jsp http/1.1,我们的简单的服务器的思路就是从request中得到URI后在你的服务器上找到这个资源,比如是一个静态的html页面,然后把它发送给浏览器。记住URI是相对于你的HTTP服务器的根目录的,所以以/来开头。接下来的部分是请求头信息它们都是以name:value这样的方式构成的,这里不再多介绍了。在Header和Entity body之间有一空行叫做CRLF,这用来标记Entity body的开始的,意思是下面的是传输的数据了。

HTTP响应和请求非常相似,同样包括三个部分:

Protocol-Status code-Description

Response headers

Entity body

下面是一个具体的例子:

HTTP/1.1 200 OK

Server: Microsoft-IIS/4.0

Date: Mon, 3 Jan 1998 13:13:33 GMT

Content-Type: text/html

Last-Modified: Mon, 11 Jan 1998 13:23:42 GMT

Content-Length: 112

something in html style......................

通常在J2ME联网中我们需要判断响应的状态码来决定下一步的操作,比如200代表连接成功。现在你应该清楚为什么这么做了吧。同样在Header和Entity body中有一个CRLF分割。

现在我们来看看java中的Socket类,socket其实是对编程语言的一种抽象,它提供了在网络上端对端访问的可能,但是它并不依赖于编程语言,你完全可以使用java和c语言通过socket来进行通信,在java中是通过java.net.Socket来实现的,当你要构建一个socket的时候,你只是需要调用它的构造器

public Socket(String host,int port),其中host代表目标主机的地址或名字,port代表端口,比如80。当我们创建了一个Socket的实例后我们就可以进行通信了,如果你要基于字节来通信,那么你可以通过调用getOutputStream()和getInputStream()来得到OutputStream和InputStream的对象,如果你是基于字符通信的话那么你可以用PrintWriter和BufferedReader进行二次包装,例如PrintWriter pw = new PrintWriter(socket.getOutputStream(),true)。下面是简单的使用socket通信的代码片断,实现了向127.0.0.1:8080发送Http请求的功能

Socket socket = new Socket("127.0.0.1", "8080");

OutputStream os = socket.getOutputStream();

boolean autoflush = true;

PrintWriter out = new PrintWriter( socket.getOutputStream(), autoflush );

BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ));

// send an HTTP request to the web server

out.println("GET /index.jsp HTTP/1.1");

out.println("Host: localhost:8080");

out.println("Connection: Close");

out.println();

// read the response

boolean loop = true;

StringBuffer sb = new StringBuffer(8096);

while (loop) {

if ( in.ready() ) {

int i=0;

while (i!=-1) {

i = in.read();

sb.append((char) i);

}

loop = false;

}

Thread.currentThread().sleep(50);

}

// display the response to the out console

System.out.println(sb.toString());

socket.close();

接下来介绍与Socket类对应的ServerSocket类的使用,与Socket代表客户端不同的是,ServerSocket是代表服务器端的,因为它必须在某个端口不停的监视是否有客户端连接进来。通过调用ServerSocket的构造器我们可以建立起监听特定端口的Server。例如

new ServerSocket(8080, 1, InetAddress.getByName("127.0.0.1"));

这样我们在本机的8080端口建立起来了ServerSocket。当你调用ServerSocket的accept()方法后,只有有连接进来的时候,这个方法才会返回一个Socket的对象,这样你就可以使用这个实例来接受或者发送数据了。记住当我们传输数据结束后要记得调用clos()方法来释放资源。

本文主要为Http服务器的实现做铺垫,在后面的文章内将主要讲述如何实现并运行我们基于Java实现的Http服务器。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有