Java实现简易Web服务器

网友投稿 176 2023-07-21


Java实现简易Web服务器

众所周知Web服务器与客户端之间的通信是使用HTTP协议的。HTTP是一个客户端和服务器端请求和应答的标准(TCP)。因为HTTP协议是基于TCP协议的,所以我将使用java中的Socket完成这个简易的Web服务器。关于HTTP更详细的资料,各位可以查阅相关资料进行了解。

在服务器编写之前,我们还是先来看一下浏览器与服务器之间通信的规则到底如何。

首先,我们是用ServerSocket来模拟一个服务端,通过浏览器访问,查看浏览器请求的内容:

import java.io.BufferedWriter;

import java.io.InputStream;

import java.io.OutputStreamWriter;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.Socket;

import org.junit.Test;

/**

* HTTP协议测试

*

* @author jianggujin

*

*/

public class HQHttpProtocolTest

{

@Test

public void server() throws Exception

{

ServerSocket serverSocket = new ServerSocket(80);

Socket socket = serverSocket.accept();

InputStream stream = socket.getInputStream();

int r = -1;

while ((r = stream.read()) != -1)

{

System.out.print((char) r);

}

}

}

使用junit运行,并通过浏览器访问:http://127.0.0.1,我们可以看到控制台上输出浏览器的请求内容如下:

GET / HTTP/1.1

Host: 127.0.0.1

Connection: keep-alive

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537

.36

Accept-Encoding: gzip,deflate,sdch

Accept-Language: zh-CN,zh;q=0.8

为了更好的分析请求内容,我们编写一个HTML页面提交一些数据,再次查看请求内容:

在输入框中输入bob,点击按钮提交,观察控制台输出:

POST /?test=123 HTTP/1.1

Host: 127.0.0.1

Connection: keep-alive

Content-Length: 8

Cache-Control: max-age=0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Origin: null

User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537

.36

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

Accept-Encoding: gzip,deflate,sdch

Accept-Language: zh-CN,zh;q=0.8

name=bob

我们来分析一下这段请求内容:

第一行:由三部分组成,中间以空格分开,第一部分为请求方法(GET、POST),第二部分为请求路径以及查询参数,第三部分为HTTP协议版本(HTTP/1.1)

第二行到第十行:请求的头信息,请求头名称与值之间通过:分隔

第十一行:空行

第十二行:提交的表单内容

综上,我们可以得到如下结论:请求信息第一行为请求方法、请求路径以及查询参数、HTTP协议版本,通过\r\n换行后紧跟着请求头信息,各头信息之间通过\r\n换行,请求头信息结束后跟着一个空行,空行之后紧跟着一行为请求数据,需要注意的是,这里面只模拟了最简单的表单提交,至于复杂的文件提交等,这里面不讨论,请求内容格式略有不同。

至此,客户端请求的内容我们已经知道了,下面我们再来看看服务端在接收到请求后响应数据的格式,我们新建一个Web项目用于测试,编辑Html页面内容如下:

启动服务器,然后编写客户端测试代码,获得服务端返回数据:

import java.io.BufferedWriter;

import java.io.InputStream;

import java.io.OutputStreamWriter;

import java.net.ServerSocket;

import java.net.Socket;

import org.junit.Test;

/**

* HTTP协议测试

*

* @author jianggujin

*

*/

publhttp://ic class HQHttpProtocolTest

{

public void server() throws Exception

{

ServerSocket serverSocket = new ServerSocket(80);

Socket socket = serverSocket.accept();

InputStream stream = socket.getInputStream();

// BufferedInputStream inputStream = new BufferedInputStream(stream);

int r = -1;

while ((r = stream.read()) != -1)

{

System.out.print((char) r);

}

}

@Test

public void client() throws Exception

{

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

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(

socket.getOutputStream()));

writer.write("GET /Servlet/test.html HTTP/1.1\r\n");

writer.write("Host: 127.0.0.1\r\n");

writer.write("Connection: keep-alive\r\n");

writer.write("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n");

writer.write("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36\r\n");

writer.write("Accept-Encoding: gzip,deflate,sdch\r\n");

writer.write("Accept-Language: zh-CN,zh;q=0.8\r\n");

writer.write("\r\n");

writer.fRLvqHlush();

InputStream stream = socket.getInputStream();

int r = -1;

while ((r = stream.read()) != -1)

{

System.out.print((char) r);

}

}

}

运行程序获得服务器返回内容如下:

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Accept-Ranges: bytes

ETag: W/"129-1456125361109"

Last-Modified: Mon, 22 Feb 2016 07:16:01 GMT

Content-Type: text/html

Content-Length: 129

Date: Mon, 22 Feb 2016 08:08:32 GMT

同样的,我们来分析一下这段返回消息:

第一行由三部分组成,中间以空格分开,第一部分为HTTP协议版本(HTTP/1.1),第二部分为响应状态码,第三部分为响应状态描述

第二行到第七行为响应头信息,响应头名称与值之间通过:分隔

第八行:空行

第九行到结束:响应内容

综上,我们可以得到如下结论:请求信息第一行为HTTP协议版本、响应状态码、响应状态描述,通过\r\n换行后紧跟着响应头信息,各头信息之间通过\r\n换行,响应头信息结束后跟着一个空行,空行之后紧跟着响应数据,需要注意的是,除这种响应外,其实还有其他的相应方式,比如chunk,此处不讨论,可查阅相关资料。

到现在为止,我们已经分析完了客户端的请求内容格式以及服务端相应内容的格式,这一篇就到此为止了,希望对大家的学习有所帮助。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:保障系统健康运转:掌握接口稳定性测试关键要点
下一篇:接口文档测试用例:教你怎么写接口文档测试用例,立马学会
相关文章

 发表评论

暂时没有评论,来抢沙发吧~