文档章节

自己动手创建一个Web Server(非Socket实现)

IT周见智
 IT周见智
发布于 2015/06/05 17:18
字数 1639
阅读 16
收藏 0

目录

  • 介绍
  • Web Server在Web架构系统中的作用
  • Web Server与Web网站程序的交互
  • HTTPListener与Socket两种方式的差异
  • 附带Demo源码概述
  • Demo效果截图
  • 总结

 

介绍

本篇文章主要介绍使用HTTPListener类型自己动手创建一个Web Server,创建的Web Server能够接收来自浏览器端的HTTP请求,并且能够传递给对应的Web站点进行处理,最后将处理结果(Html或者其他格式)返回给浏览器。

博主前面曾经介绍过使用Socket模拟Web Server的运行过程、Socket模拟浏览器发送HTTP请求过程。分别参见:

本篇文章并没有使用Socket去实现,而是使用另外一种封装程度更高、更抽象的System.Net.HTTPListener类型实现。

 

Web ServerWeb架构系统中的作用

Web Server在一个B/S架构系统中起到的作用不仅多而且相当重要,Web开发者大部分时候并不需要了解它的详细工作机制。虽然不同的Web Server可能功能并不完全一样,但是以下三个功能几乎是所有Web Server必须具备的:

  • 接收来自浏览器端的HTTP请求
  • 将请求转发给指定Web站点程序(后者由Web开发者编写,负责处理请求)
  • 向浏览器发送请求处理结果

下图显示Web Server在整个Web架构系统中所处的重要位置:

如上图,Web Server起到了一个“承上启下”的作用(虽然并没有“上下”之分),它负责连接用户和Web站点。

我们可以看到,Web Server默认情况下需要与Web开发者编写的Web网站程序“通信”(图中假设三个网站均在一个Web Server上),那么这里怎么处理呢?实时上,任何Web开发者在使用某个平台开发Web程序时,必须遵守某些“规则”,比如使用到某些框架等。遵守了这些规则,开发出来的网站就可以放到Web Server上,这是不是有点像“程序扩展”的意思?

 

Web ServerWeb网站程序的交互

每个网站就像一个个“插件”,只要网站开发过程中遵循了Web Server提出的规则,那么该网站就可以“插”在Web Server上,我们便可以通过浏览器访问网站。

理论上讲,每个Web Server均是一个宿主,而每个网站均是一个插件(plug-in)。Web Server主要负责通讯等功能,网站程序主要负责数据处理。

至于“宿主”怎样与“插件”通信,请参见博主前面的一篇文章“应用程序扩展”。

由于每个Web Server均能持续接收HTTP请求,因此每个Web Server中均应该存在一个类似下图所示的循环结构:

如上图,为了提高Web Server接收HTTP请求的效率,图中虚线框一般采用异步处理,请求处理过程不会影响整个循环。

 

HTTPListenerSocket两种方式的差异

事实上,HTTP协议是应用层协议。数据在传输层上依然是采用TCP进行传输的,因此,自己动手采用Socket方式完全能够模拟出Web Server的工作过程(正如文章开头讲到的)。博主前面有一篇博客讲述“使用Socket请求Web Server”,其实就是使用Socket来模拟浏览器的通讯行为。在.NET中的System.Net命名空间中,包含一些更高层次、更抽象的类型也可以完成对浏览器的模拟,如System.Net.HTTPWebRequest和System.Net.HTTPWebResponse等类型,至于它们和直接使用Socket有什么区别,请参见下表:

分类

Web Server端

浏览器端

优点

缺点

Socket方式

Socket.Accept

负责接收浏览器端的Socket连接请求

 

Socket.Receive

负责接收浏览器发送的数据

 

Socket.Send

负责向浏览器发送数据

Socket.Connect

负责向Web Server发送连接请求

 

Socket.Receive

负责接收Web Server发来的回复

 

Socket.Send

负责向Web Server发送请求

更底层,灵活性更强

更底层,需要充分了解HTTP协议、TCP/IP协议

System.Net命名空间中的类型

HTTPListener.GetContext

负责接收浏览器端的HTTP请求

 

HTTPListenerRequest

该类负责接收浏览器端的请求(Request)数据

 

HTTPListenerResponse

该类负责向浏览器发送回复(Response)数据

HTTPWebRequest

该类负责向Web Server发送HTTP请求

 

HTTPWebResponse

该类负责接收来自Web Server发来的回复

更高层级别的抽象,不需要过多的了解HTTP、TCP等通讯知识

更抽象,用法固定(不过需要的都已经包含)

可以看到,以上两种方式最终达到的效果其实是一样的。

注:请区分HTTPWebRequest与Asp.NET中的HTTPRequest。后者只能用在Asp.NET中,属于Asp.NET中的核心对象。同理请区分HTTPWebResponse与Asp.NET中的HTTPResponse。它们的命名空间分别为:System.NET和System.Web

 

附带Demo源码概述

源码包含三个项目,分别为:

  • HTTPServer:模拟的一个Web Server(不足70行代码)
  • HTTPUtility:一个抽象层,专门为了Web Server与网站程序之间的交互。这里充分应用了“依赖倒置原则(DIP)”,目的就是降低Web Server与网站程序之间的耦合度。
  • MyWebsite:一个(模拟的)网站程序,需要依赖HTTPUtility。

如果将Demo中的三块与现实一一类比,那么HTTPServer便是IIS/Apache,HTTPUtility便是我们开发Web程序时需要使用到的框架/原则,MyWebsite便是我们开发出来的Web网站程序。

将编译之后的MyWebsite项目DLL文件拷贝到HTTPServer可执行程序同一目录下的web文件夹中即可(类似一个网站发布的过程)。打开HTTPServer.exe文件运行,即可在浏览器中访问MyWebsite网站。

源码中注释比较详细,在此就不多说源码的事情。

 

Demo效果截图

 

 

总结

两种方式实现的过程、代码结构均类似。主要掌握两点:

  • Web Server中的循环结构(泵),负责持续接收请求
  • Web Server与网站程序(Plug-in)之间的交互

作为一个Web开发者,了解这些几乎用不到的知识也是必需的。

源码下载:http://files.cnblogs.com/xiaozhi_5638/HTTP_Web_Server.rar

转发请保留原文链接地址。

© 著作权归作者所有

共有 人打赏支持
IT周见智

IT周见智

粉丝 10
博文 61
码字总数 185891
作品 0
西青
简单的java web服务器实例

编写使用java语言实现的Web服务器,主要通过使用java socket 编程来实现,使用java socket编程不仅可以编写web服务器,还可以编写其他网络应用。 WebServer.java package webbook.chapter2;...

zkool
2012/08/12
0
0
用Python脚本定制自己的Web服务器

标题很宏伟,实现很遥远。 首先要说明这其实是一个不可能完成的任务,至少不是一片博文就能完成的任务。避免浪费看到标题而满心期待同道的时间。 主要是想以Apache为蓝本,通过Python脚本的方...

散居江湖
2013/01/23
0
0
Mac OS X Leopard: 配置Apache, PHP, SQLite, MySQL, and phpMyAdmin(三)

前面的一二分别介绍了Apache,PHP和MySQL的安装配置, 而phpMyAdmin的安装, 其实更象一个php应用程序的安装, 后面我准备安装一个Wiki或者CMS系统. 参见: Mac OS X Leopard: 配置Apache, PHP, ...

junwong
2012/03/09
0
0
How to debug with IntelliJ IDEA + Grails 2.3.x

问题: 最近访问grails.org,看到grails framework已经发展到2.3.x了,不免想尝尝鲜。下载了最新的grails-2.3.x之后,创建了一个新的grails app。 添加Book domain对象后有自动生成了BookCon...

紫禁校尉
2014/03/31
0
0
UNIX Domain Socket IPC

UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的。 使...

nothingfinal
2012/05/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java中的移位运算符

国庆给自己放了个小长期二十几天,回来继续更新专栏 上一篇文章我们说了Java里的二进制,知道了计算机是以0和1来处理数据的,在阅读源码的过程中,经常会看到这些符号<< ,>>,>>>,这些符号...

SuShine
21分钟前
2
0
linux版QQ

下载地址在这 http://yun.tzmm.com.cn/index.php/s/XRbfi6aOIjv5gwj Appimage包不用做什么别的处理,安装啥的都不需要。。找到文件所在目录,终端中修改一下文件的权限 chmod 777 QQ-2017112...

悲催的古灵武士
26分钟前
1
0
咕泡-MyBatis 实用篇作业

1. Mapper在spring管理下其实是单例,为什么可以是一个单例? 首先,mapper 内部不包含 成员字段,无状态单例是安全的 另外,一直存在不用每次调用都new 一个新实例 2. MyBatis在Spring集成下...

职业搬砖20年
30分钟前
2
0
MQTT协议的初浅认识之连接建立

MQTT百科 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布...

亚林瓜子
46分钟前
1
0
OpenStack部署都有哪些方式

对于每一个刚接触到OpenStack的新人而言,安装无疑是最困难的,同时这也客观上提高了大家学习OpenStack云计算的技术门槛。想一想,自己3年前网上偶然接触到OpenStack时,一头茫然,手动搭建一...

tututu_jiang
47分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部