欢迎光临
我们一直在努力

手写简易WEB服务器

今天我们来写一个类似于Tomcat的简易服务器。可供大家深入理解一下tomcat的工作原理,本文仅供新手参考,请各位大神指正!
首先我们要准备的知识是:
Socket编程
HTML
HTTP协议
服务器编写
反射
XML解析
有了上面的知识,我们可以开始写我们的代码了~~
1、首先我们要应用Socket编程写一个简单的服务端用来接收服务器端发来的请求:

以下是浏览器访问上述服务器时产生的请求内容:HTTP知识补充:

以下是浏览器访问上述服务器时产生的请求内容:
POST请求内容:(远不止这些,大家可以通过wireshark来抓包分析请求协议格式
POST / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Content-Length: 25
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 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8

username=ss&password=aaaa
GET请求内容:
GET /?username=aa&password=ssss HTTP/1.1
Host: localhost:8888
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 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
下面给出一个服务器响应内容:
通用头域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。
HTTP/1.1 200 OK
Cache-Control:private, max-age=0, no-cache:
Control说明:
Cache-Control指定请求和响应遵循的缓存机 制。
Public指示响应可被任何缓存区缓存。
Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
no-cache指示请求或响应消息不能缓存
no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

Content-Type:image/gif
Content-Type说明:
Content-Type实体头用于向接收方指示实体的介质类型,指定HEAD方法送到接收方的实体介质类型,或GET方法发送的请求介质类型Content-Range实体头

Date:Sat, 08 Aug 2015 03:23:23 GMT
Date说明:
Date头域表示消息发送的时间,时间的描述格式由rfc822定义。

Pragma:no-cache
Pragma说明:
Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache-Control:no-cache相同。

Server:apache
Server说明:
Server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。

Content-Length:43
重点补充:
Status-Code的第一个数字定义响应的类别,后两个数字没有分类的作用。第一个数字可能取5个不同的值:
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求

以上补充有利于项目排错哦~~很重要哦~~

2、我们根据上面的服务器相应内容来写一个针对浏览器客户端的响应:

3、封装response和request
3.1封装response
步骤:
A:构建报文头
B:构建响应的HTML正文内容
C:将报文头和HTML正文内容发送给客户端(浏览器)

3.2封装request
步骤:
A:接受浏览器发送的请求
B:解析浏览器发送来的请求

3.3 此时我们可以将代码优化一下
新建servlet类来转码处理请求和响应的业务

此时我们的服务器端可以简化为:

4、多线程实现
写到这里我们会发现,此时的代码只能处理一个请求,而现实中的情况是往往会有很多很多的客户端发请求,所以这里我们要用多线程来实现
因此我们把与客户端浏览器的通信封装到一个线程当中。

此时我们的服务器只能应对单一的请求与响应,结束后会自动关闭,而现实中的服务器是一直开启等待客户端的请求。
所以我们的服务器端可以优化为:

到此时我们会发现我们发过来的请求会有很多,也就意味着我们应该会有很多的servlet,例如:RegisterServlet、LoginServlet等等还有很多其他的访问。
那么我们要用到类似于工厂模式的方法处理,来随时产生很多的servlet,来满足不同的功能性的请求。
那么我们要抽象servlet。
在我们抽象servlet之前,我们先来思考一个问题:
我们会写很多的servlet,那么我们怎么将请求与各种的servlet相匹配呢?
接下来我们要先写一个关于servlet的上下文,来封装servlet与请求。说到这里你是不是想到了什么呢??

其实说白了servletContext这个类就是一个容器,用来存放请求与对应的Servlet的。
那么接下来我们模拟一下,往这个容器里面存放请求与对应的Servlet,但是在这之前我们需要有不同的servlet,所以我们接下来要把Servlet进行抽象,
以便于我们可以随意产生不同的servlet。

上面的抽象其实很简单,那么当我们抽象结束后,我们写一个WebApp类来存储一些我们会用到的servlet上下文,并且提供获取他们的方法:

接下来我们要修改一下分发的程序了:

这样一个简易的原理过程就出来了,别急,还没有结束呢。
我们现在写的代码用来存储servlet上下文的时候用的是Servlet抽象类吧?就是说我们每次存储的时候都要存储一个类,这样是不是有点消耗内存呢?如果换成字符串呢?
还有一点就是如果我们每次修改这个类是不是都要重启一下服务器?是不是很麻烦??所以。。。你想到了什么?
随你便啦~~其实如果你写过非框架的web应用,那么应该接触过配置文件。那么应该想到的就是web.xml
接下来讲一下配置文件吧,哈哈哈哈哈哈
一说到配置文件,肯定是要解析配置文件的,一解析配置又牵扯到类与对象,少不了的技术就是反射机制哦!!
首先让我们稍微修改一下ServletContext类;

那么接下来我们要做的就是解析XML文件并且将解析好的值放入servlet上下文中。
解析xml文件之前我们先要用实体类来封装xml文件

然后再解析XML文件并且将解析好的值放入servlet上下文中。

 

这里还需要一个XMLHandler处理器来处理xml文件

万事具备只欠东风!---->处理一下分发的类:

经过以上的分析以及代码的书写,一个简易的web服务器就这样诞生了!
各位看官可以动手尝试一下哦~~
当然代码有很多的地方还很值得去优化和修正,希望有心的大神能指正错误,我会及时修正!!

  注意:此文仅适用于刚入门的同学,帮助理解服务器原理。

附:手写服务器包结构(最终整理)

 

  • 海报
海报图正在生成中...
赞(0) 打赏
声明:
1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。
2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。
3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。
4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。
文章名称:《手写简易WEB服务器》
文章链接:https://www.456zj.com/634.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址