JAVA简易WEB服务器(一)

原创 2016年02月22日 16:25:05

这一篇博客开始将和大家一起使用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页面提交一些数据,再次查看请求内容:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<form method="post" action="http://127.0.0.1?test=123">
<input type="text" name="name"/>
<input type="submit"/>
</form>
</body>
</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页面内容如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>this is test page.
</body>
</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
 * 
 */
public 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.flush();
      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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>this is test page.
</body>
</html>

同样的,我们来分析一下这段返回消息:
第一行由三部分组成,中间以空格分开,第一部分为HTTP协议版本(HTTP/1.1),第二部分为响应状态码,第三部分为响应状态描述
第二行到第七行为响应头信息,响应头名称与值之间通过:分隔
第八行:空行
第九行到结束:响应内容
综上,我们可以得到如下结论:请求信息第一行为HTTP协议版本、响应状态码、响应状态描述,通过\r\n换行后紧跟着响应头信息,各头信息之间通过\r\n换行,响应头信息结束后跟着一个空行,空行之后紧跟着响应数据,需要注意的是,除这种响应外,其实还有其他的相应方式,比如chunk,此处不讨论,可查阅相关资料

到现在为止,我们已经分析完了客户端的请求内容格式以及服务端相应内容的格式,这一篇就到此为止了,接下来的博客中,我们将一步一步的进行服务器端的编写。

版权声明:本文为博主原创文章,转载请标明出处。

实战WEB 服务器(JAVA编写WEB服务器)

  一、超文本传输协议     1.1 HTTP请求     1.2 HTTP应答   二、Socket类   三、ServerSocket类   四、Web服务器实例     4.1 HttpSer...
  • turkeyzhou
  • turkeyzhou
  • 2010年04月21日 17:09
  • 20823

java实现一个简单的Web服务器

Web服务器也称为超文本传输协议服务器,使用http与其客户端进行通信,基于java的web服务器会使用两个重要的类, java.net.Socket类和java.net.ServerSocket类...
  • u012734441
  • u012734441
  • 2015年04月01日 07:31
  • 7909

一个简单web服务器的java实现

一个简单的web服务器在不考虑其性能及健壮性的情况下,通常只需实现的功能包括服务器的启动,它用于监听某一个端口,接收客户端发来的请求,并将响应结果返回给客户端。本文将介绍一个简单web服务器的实现原理...
  • shanzhizi
  • shanzhizi
  • 2014年10月18日 16:37
  • 2235

Java模拟web服务器

以前用C#的HttpListener实现过一个简易的web服务器(C#模拟web服务器),这里介绍下java实现简易的web服务器。 本地服务器作用也差不多,如与hosts文件一起使用,可以拦截或处理...
  • hzaccp3
  • hzaccp3
  • 2013年10月11日 00:08
  • 2285

用java 写的一个简单的 web 服务器(适合新手练练)

用java写的一个web,效果如下图;总结一下遇到的问题:                  1. 端口被占用,可以尝试下换端口;           2. 个别电脑装的软件类型太多,有时候接收不到...
  • u011102206
  • u011102206
  • 2013年08月06日 09:03
  • 2823

自己写一个简单的Web服务器(附Demo)

一、什么是Web服务器? 先来写个例子亲身体验一下。下面的示例代码演示了如何通过 java.net.Socket 与 java.net.ServerSocket这两个重要的类创建一个简单...
  • chuan3676
  • chuan3676
  • 2015年03月22日 22:52
  • 2287

一个简单web服务器的java实现

一个简单的web服务器在不考虑其性能及健壮性的情况下,通常只需实现的功能包括服务器的启动,它用于监听某一个端口,接收客户端发来的请求,并将响应结果返回给客户端。本文将介绍一个简单web服务器的实现原理...
  • shanzhizi
  • shanzhizi
  • 2014年10月18日 16:37
  • 2235

java实现一个简单的Web服务器

Web服务器也称为超文本传输协议服务器,使用http与其客户端进行通信,基于java的web服务器会使用两个重要的类, java.net.Socket类和java.net.ServerSocket类...
  • u012734441
  • u012734441
  • 2015年04月01日 07:31
  • 7909

用java 写的一个简单的 web 服务器(适合新手练练)

用java写的一个web,效果如下图;总结一下遇到的问题:                  1. 端口被占用,可以尝试下换端口;           2. 个别电脑装的软件类型太多,有时候接收不到...
  • u011102206
  • u011102206
  • 2013年08月06日 09:03
  • 2823

简单web服务器的设计与实现

socket web服务器
  • zdy_lsh
  • zdy_lsh
  • 2017年01月27日 19:48
  • 1272
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA简易WEB服务器(一)
举报原因:
原因补充:

(最多只允许输入30个字)