某用户利用浏览器访问 免费web服务器器上一个大小为22KB的网页,假设TCP最大报文长度是1K

(window.slotbydup=window.slotbydup || []).push({
id: '2014386',
container: s,
size: '234,60',
display: 'inlay-fix'
&&|&&0次下载&&|&&总238页&&|
您的计算机尚未安装Flash,点击安装&
试读已结束,如果需要继续阅读或下载,请使用积分()
下载:70积分
本文档由合作伙伴提供
1人评价1页
0人评价147页
2人评价2页
0人评价75页
0人评价61页
此文档归属以下专题
2人评价4个文档
所需积分:(友情提示:大部分文档均可免费预览!下载之前请务必先预览阅读,以免误下载造成积分浪费!)
(多个标签用逗号分隔)
文不对题,内容与标题介绍不符
广告内容或内容过于简单
文档乱码或无法正常显示
文档内容侵权
已存在相同文档
不属于经济管理类文档
源文档损坏或加密
若此文档涉嫌侵害了您的权利,请参照说明。
我要评价:
价格:70积分VIP价:56积分【图文】研究生习题选讲(计算机网络)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
研究生习题选讲(计算机网络)
&&计算机网络期末考试资料
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢比特客户端
您的位置:
详解大数据
详解大数据
详解大数据
详解大数据
HTTP响应报文与工作原理详解
关键字:HTTP
  超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议。HTTP 是一种请求/响应式的协议,即一个客户端与建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应。
  HTTP 请求报文
  HTTP 请求报文由请求行、请求头部、空行 和 请求包体 4 个部分组成,如下图所示:
  下面对请求报文格式进行简单的分析:
  请求行:请求行由方法字段、URL 字段 和HTTP 协议版本字段 3 个部分组成,他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;
  ● GET:当客户端要从服务器中读取某个资源时,使用GET 方法。GET 方法要求服务器将URL 定位的资源放在响应报文的部分,回客户端,即向服务器请求某个资源。使用GET 方法时,请求参数和对应的值附加在 URL 后面,利用一个问号(“?”)代表URL 的结尾与请求参数的开始,传递参数长度受限制。例如,/index.jsp?id=100&op=bind。
  ● POST:当客户端给服务器提供信息较多时可以使用POST 方法,POST 方法向服务器提交数据,比如完成表单数据的提交,将数据提交给服务器处理。GET 一般用于获取/查询资源信息,POST 会附带用户数据,一般用于更新资源信息。POST 方法将请求参数在HTTP 请求数据中,以名称/值的形式出现,可以传输大量数据;
  请求头部:请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
  ● User-Agent:产生请求的类型;
  ● Accept:客户端可识别的响应内容类型列表;星号 “ * ” 用于按范围将类型分组,用 “ */* ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型;
  ● Accept-Language:客户端可接受的自然语言;
  ● Accept-Encoding:客户端可接受的编码压缩格式;
  ● Accept-Charset:可接受的应答的字符集;
  ● Host:请求的主机名,允许多个同处一个IP 地址,即虚拟主机;
  ● connection:连接方式(close 或 keepalive);
  ● Cookie:于客户端扩展字段,向同一域名的服务端发送属于该域的
  空行:最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头;
  请求包体:请求包体不在 GET 方法中使用,而是在POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求包体相关的最常使用的是包体类型 Content-Type 和包体长度 Content-L
  HTTP 响应报文
  HTTP 响应报文由状态行、响应头部、空行 和 响应包体 4 个部分组成,如下图所示:
  下面对响应报文格式进行简单的分析:
  状态行:状态行由 HTTP 协议版本字段、状态码和状态码的描述文本 3 个部分组成,他们之间使用空格隔开;
  ● 状态码由三位数字组成,第一位数字表示响应的类型,常用的状态码有五大类如下所示:
  1xx:表示服务器已接收了客户端请求,客户端可继续发送请求;
  2xx:表示服务器已成功接收到请求并进行处理;
  3xx:表示服务器要求客户端重定向;
  4xx:表示客户端的请求有非法内容;
  5xx:表示服务器未能正常处理客户端的请求而出现意外错误;
  ● 状态码描述文本有如下取值:
  200 OK:表示客户端请求成功;
  400 Bad Request:表示客户端请求有语法错误,不能被服务器所理解;
  401 Unauthonzed:表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用;
  403 Forbidden:表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因;
  404 Not Found:请求的资源不存在,例如,输入了错误的URL;
  500 Internal Server Error:表示服务器发生不可预期的错误,导致无法完成客户端的请求;
  503 Service Unavailable:表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常;
  响应头部:响应头可能包括:
  Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源;
  Server:Server 响应报头域包含了服务器用来处理请求的软件信息及其版本。它和 User-Agent 请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和的信息。
  Vary:指示不可缓存的请求头列表;
  Connection:连接方式;
  对于请求来说:close(告诉或者,在完成本次请求的响应后,断开连接,不等待本次连接的后续请求了)。keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求);
  对于响应来说:close(连接已经关闭); keepalive(连接保持着,在等待本次连接的后续请求); Keep-Alive:如果浏览器请求保持连接,则该头部表明希望WEB 服务器保持连接多长时间(秒);例如:Keep-Alive:300;
  WWW-Authenticate:WWW-Authenticate响应报头域必须被包含在401 (未授权的)响应消息中,这个报头域和前面讲到的Authorization 请求报头域是相关的,当客户端收到 401 响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了Authorization 报头域的请求;
  空行:最后一个响应头部之后是一个空行,发送回车符和换行符,通知服务器以下不再有响应头部。
  响应包体:服务器返回给客户端的文本信息;
  HTTP 工作原理
  HTTP 协议采用请求/响应模型。客户端向服务器发送一个请求报文,服务器以一个状态作为响应。
  以下是 HTTP 请求/响应的步骤:
  ● 客户端连接到web服务器:HTTP 客户端与web服务器建立一个 TCP 连接;
  ● 客户端向服务器发起 HTTP 请求:通过已建立的TCP 连接,客户端向服务器发送一个请求报文;
  ● 服务器接收 HTTP 请求并返回 HTTP 响应:服务器解析请求,定位请求资源,服务器将资源副本写到 TCP 连接,由客户端读取;
  ● 释放 TCP 连接:若connection 模式为close,则服务器主动关闭TCP 连接,客户端被动关闭连接,释放TCP 连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
  ● 客户端浏览器解析HTML内容:客户端将服务器响应的 html 文本解析并显示;
  例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程:
  1、浏览器向请求解析该 URL 中的域名所对应的 IP 地址;
  2、解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立 TCP 连接;
  3、浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
  4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
  5、释放 TCP 连接;
  6、浏览器将该 html 文本并显示内容;
  HTTP 无状态性
  HTTP 协议是无状态的(stateless)。也就是说,同一个客户端第二次访问同一个服务器上的页面时,服务器无法知道这个客户端曾经访问过,服务器也无法分辨不同的客户端。HTTP 的无状态特性简化了服务器的设计,使服务器更容易支持大量并发的HTTP 请求。
  HTTP 持久连接
  HTTP1.0 使用的是非持久连接,主要缺点是客户端必须为每一个待请求的对象建立并维护一个新的连接,即每请求一个文档就要有两倍RTT 的开销。因为同一个页面可能存在多个对象,所以非持久连接可能使一个页面的下载变得十分缓慢,而且这种短连接增加了传输的负担。HTTP1.1 使用持久连接keepalive,所谓持久连接,就是服务器在发送响应后仍然在一段时间内保持这条连接,允许在同一个连接中存在多次数据请求和响应,即在持久连接情况下,服务器在发送完响应后并不关闭TCP 连接,而客户端可以通过这个连接继续请求其他对象。
  HTTP/1.1 协议的持久连接有两种方式:
  ● 非流水线方式:客户在收到前一个响应后才能发出下一个请求;
  ● 流水线方式:客户在收到 HTTP 的响应报文之前就能接着发送新的请求报文;
  最后给出一个具体例子:
  Remote:116.57.254.104:80 Request URL:http://hr.tencent.com/ Request Method:GET Status Code:200 OK Request Headers GET / HTTP/1.1 Host: hr.tencent.com Connection: keep-alive Accept: text/html,application/xhtml+xml,application/q=0.9,image/webp,*/*;q=0.8 User-Agent:/5.0 (X11; i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0. Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,q=0.8,zh-CN;q=0.6,q=0.4 Cookie: pgv_pvi=; PHPSESSID=bc7onl0dojbsatscsfv79pds77; pgv_info=ssid=s; pgv_pvid=; ts_uid= Response Header HTTP/1.1 200 OK Server: nginx Date: Mon, 26 Jan :10 GMT Content-Type: text/charset=utf-8 Content-Length: 3631 Connection: keep-alive X-Powered-By: PHP/5.3.10 Expires: Thu, 19 Nov :00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Encoding: gzip
  从请求报文可以知道:
  GET / HTTP/1.1
  请求方法 GET 表示一个读取请求,将从服务器获得网页数据,/表示URL 的路径,URL 总是以/开头,/就表示首页,最后的HTTP/1.1 指示采用的 HTTP 协议版本是 1.1;请求域名如下所示:
  Host: hr.tencent.com
  响应报文如下:
  HTTP/1.1 200 OK Server: nginx
[ 责任编辑:李桢君 ]
去年,手机江湖里的竞争格局还是…
甲骨文的云战略已经完成第一阶段…
软件信息化周刊
比特软件信息化周刊提供以数据库、操作系统和管理软件为重点的全面软件信息化产业热点、应用方案推荐、实用技巧分享等。以最新的软件资讯,最新的软件技巧,最新的软件与服务业内动态来为IT用户找到软捷径。
商务办公周刊
比特商务周刊是一个及行业资讯、深度分析、企业导购等为一体的综合性周刊。其中,与中国计量科学研究院合力打造的比特实验室可以为商业用户提供最权威的采购指南。是企业用户不可缺少的智选周刊!
比特网络周刊向企业网管员以及网络技术和产品使用者提供关于网络产业动态、技术热点、组网、建网、网络管理、网络运维等最新技术和实用技巧,帮助网管答疑解惑,成为网管好帮手。
服务器周刊
比特服务器周刊作为比特网的重点频道之一,主要关注x86服务器,RISC架构服务器以及高性能计算机行业的产品及发展动态。通过最独到的编辑观点和业界动态分析,让您第一时间了解服务器行业的趋势。
比特存储周刊长期以来,为读者提供企业存储领域高质量的原创内容,及时、全面的资讯、技术、方案以及案例文章,力求成为业界领先的存储媒体。比特存储周刊始终致力于用户的企业信息化建设、存储业务、数据保护与容灾构建以及数据管理部署等方面服务。
比特安全周刊通过专业的信息安全内容建设,为企业级用户打造最具商业价值的信息沟通平台,并为安全厂商提供多层面、多维度的媒体宣传手段。与其他同类网站信息安全内容相比,比特安全周刊运作模式更加独立,对信息安全界的动态新闻更新更快。
新闻中心热点推荐
新闻中心以独特视角精选一周内最具影响力的行业重大事件或圈内精彩故事,为企业级用户打造重点突出,可读性强,商业价值高的信息共享平台;同时为互联网、IT业界及通信厂商提供一条精准快捷,渗透力强,覆盖面广的媒体传播途径。
云计算周刊
比特云计算周刊关注云计算产业热点技术应用与趋势发展,全方位报道云计算领域最新动态。为用户与企业架设起沟通交流平台。包括IaaS、PaaS、SaaS各种不同的服务类型以及相关的安全与管理内容介绍。
CIO俱乐部周刊
比特CIO俱乐部周刊以大量高端CIO沙龙或专题研讨会以及对明星CIO的深入采访为依托,汇聚中国500强CIO的集体智慧。旨为中国杰出的CIO提供一个良好的互融互通 、促进交流的平台,并持续提供丰富的资讯和服务,探讨信息化建设,推动中国信息化发展引领CIO未来职业发展。
IT专家新闻邮件长期以来,以定向、分众、整合的商业模式,为企业IT专业人士以及IT系统采购决策者提供高质量的原创内容,包括IT新闻、评论、专家答疑、技巧和白皮书。此外,IT专家网还为读者提供包括咨询、社区、论坛、线下会议、读者沙龙等多种服务。
X周刊是一份IT人的技术娱乐周刊,给用户实时传递I最新T资讯、IT段子、技术技巧、畅销书籍,同时用户还能参与我们推荐的互动游戏,给广大的IT技术人士忙碌工作之余带来轻松休闲一刻。
微信扫一扫
关注Chinabyte开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?&纸上得来终觉浅,绝知此事要躬行&,于是我们自己模拟一个简单的Web服务器来体会一下。
一、请求-处理-响应模型
1.1 基本过程介绍
  每一个HTTP请求都会经历三个步凑:请求-处理-响应:每当我们在浏览器中输入一个URL时都会被封装为一个HTTP请求报文发送到Web服务器,而Web服务器则接收并解析HTTP请求报文,然后针对请求进行处理(返回指定的HTML页面、CSS样式表、JS脚本文件亦或是加载动态页面生成HTML并返回)。最后将要返回的内容转为输出流并封装为HTTP响应报文发送回浏览器。
  当然,浏览器接收到响应报文后会加载HTML、CSS与JS并显示在页面中,最后成为我们看到的最终效果。
1.2 通信过程介绍
  Web服务器本质上来说就是一个Socket服务端,在不停地接受着客户端的请求,然后针对每一个客户端的请求进行处理,处理完毕就即时关闭连接。而我们的浏览器则是一个Socket客户端,通过TCP协议向服务端发送HTTP请求报文。
About:Socket非常类似于电话插座,以一个电话网为例:电话的通话双方相当于相互通信的2个程序,电话号码就是IP地址。任何用户在通话之前,首先要占有一部电话机,相当于申请一个Socket;同时要知道对方的号码,相当于对方有一个固定的Socket。然后向对方拨号呼叫,相当于发出连接请求。对方假如在场并空闲,拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向Socket发送数据和从Socket接收数据。通话结束后,一方挂起电话机相当于关闭socket,撤消连接。
1.3 HTTP协议基础
  Internet的基本协议是TCP/IP协议(传输控制协议和网际协议),目前广泛使用的 FTP、HTTP(超文本传输协议)、Archie Gopher都是建立在TCP/IP上面的应用层协议,不同的协议对应不同的应用。而HTTP协议是Web应用所使用的主要协议。
  HTTP协议是基于请求响应模式的。客户端向服务器发送一个请求,请求头包含请求的方法、 URI、协议版本、以及包含请求修饰符、客户端信息和内容的类似MIME的消息结果。服务器则以一个状态行作为响应,相应的内容包括消息协议的版本、成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。
  HTTP是无状态协议,依赖于瞬间或者近乎瞬间的请求处理。请求信息被立即发送,理想的情况是 没有延时的进行处理,不过,延时还是客观存在的。HTTP有一种内置的机制,在消息的传递时间上由一定的灵活性:超时机制。一个超时就是客户机等待请求 消息的返回信息的最长时间。
  (1)HTTP请求报文示例
  (2)HTTP响应报文示例
TIP:关于HTTP协议的详细介绍,可以浏览一下小坦克大神的这篇:
二、关键设计思路
2.1 要实现的功能
  (1)处理用户的静态文件请求:主要是指html/css/js文件的请求;
  (2)处理用户的动态文件请求:这里只处理ASP.NET请求,即ashx与aspx文件的请求;
2.2 要封装的类
  (1)HttpRequest、HttpResponse与HttpContext类
  根据我们对ASP.NET请求处理机制的分析,我们知道在HttpRuntime的ProcessRequest方法中构造了一个HttpContext对象。在HttpContext的构造函数中,根据HttpWorkerRequest对象创建了HttpContext对象,这是一个重要的Http上下文对象,两个重要类型的字段也随之被初始化:HttpRequest对象和HttpResponse对象。因此,我们在设计时也可以设计一个HttpContext类将HttpRequest和HttpResponse两个实例进行封装。
TIP:有关ASP.NET请求处理机制的分析,可以浏览我的另外一篇文章:
  (2)IHttpHandler接口与实现IHttpHandler接口的HttpApplication类
  针对每个Http请求都有一个抽象的HttpApplication对象来进行处理,而为了考虑扩展性(可以是ashx,也可以是aspx),封装了一个IHttpHandler接口,让不同的处理对象实现这个接口即可。IHttpHandler接口很简单,就声明了一个ProcessRequest方法,每个实现的类只需要实现这个方法即可。
2.3 总体设计流程
三、关键代码实现
3.1 开启Socket服务监听浏览器端的HTTP请求
private void btnStart_Click(object sender, EventArgs e)
// 创建Socket-&绑定IP与端口-&设置监听队列的长度-&开启监听连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketWatch.Bind(new IPEndPoint(IPAddress.Parse(txtIPAddress.Text), int.Parse(txtPort.Text)));
socketWatch.Listen(10);
// 创建Thread-&后台执行
threadWatch = new Thread(ListenClientConnect);
threadWatch.IsBackground = true;
threadWatch.Start(socketWatch);
isEndService = false;
txtIPAddress.ReadOnly = true;
txtPort.ReadOnly = true;
btnStart.Enabled = false;
ShowMessage("~_~消息:【您已成功启动Web服务!】");
private void ListenClientConnect(object obj)
Socket socketListen = obj as S
while (!isEndService)
Socket proxSocket = socketListen.Accept();
byte[] data = new byte[1024 * 1024 * 2];
int length = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);
// Step1:接收HTTP请求
string requestText = Encoding.Default.GetString(data, 0, length);
HttpContext context = new HttpContext(requestText);
// Step2:处理HTTP请求
HttpApplication application = new HttpApplication();
application.ProcessRequest(context);
ShowMessage(string.Format("{0} {1} from {2}", context.Request.HttpMethod, context.Request.Url, proxSocket.RemoteEndPoint.ToString()));
// Step3:响应HTTP请求
proxSocket.Send(context.Response.GetResponseHeader());
proxSocket.Send(context.Response.Body);
// Step4:即时关闭Socket连接
proxSocket.Shutdown(SocketShutdown.Both);
proxSocket.Close();
  在监听线程中,通过HttpApplication类对象调用其ProcessRequest方法进行具体的处理。最重要的,处理完毕后立即通过Socket发送响应信息,并及时关闭Socket连接。
3.2 设计HttpConext类封装HttpRequest与HttpResponse
  (1)HttpContext
public class HttpContext
public HttpRequest Request { get; set; }
public HttpResponse Response { get; set; }
public HttpContext(string requestText)
Request = new HttpRequest(requestText);
Response = new HttpResponse();
  (2)HttpRequest
public class HttpRequest
public HttpRequest(string requestText)
string[] lines = requestText.Replace("\r\n", "\r").Split('\r');
string[] requestLines = lines[0].Split(' ');
// 获取HTTP请求方式、请求的URL地址、HTTP协议版本
HttpMethod = requestLines[0];
Url = requestLines[1];
HttpVersion = requestLines[2];
// 请求方式:GET or POST?
public string HttpMethod { get; set; }
// 请求URL
public string Url { get; set; }
// Http协议版本
public string HttpVersion { get; set; }
public Dictionary&string, string& HeaderDictionary { get; set; }
public Dictionary&string, string& BodyDictionary { get; set; }
  (3)HttpResponse
public class HttpResponse
// 响应状态码
public string StateCode { get; set; }
// 响应状态描述
public string StateDescription { get; set; }
// 响应内容类型
public string ContentType { get; set; }
//响应报文的正文内容
public byte[] Body { get; set; }
// 生成响应头信息
public byte[] GetResponseHeader()
string strRequestHeader = string.Format(@"HTTP/1.1 {0} {1}
Content-Type: {2}
Accept-Ranges: bytes
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Content-Length: {4}
", StateCode, StateDescription, ContentType, string.Format("{0:R}", DateTime.Now), Body.Length);
return Encoding.UTF8.GetBytes(strRequestHeader);
  这里需要注意的是在HttpResponse类中,为了生成响应头信息,需要格式化一个固定格式的信息,并且在最后保留两个CRLF(即换行符)作为头部结束标志,可以看看下面的格式说明:
3.3 设计IHttpHandler接口
public interface IHttpHandler
void ProcessRequest(HttpContext context);
  仿照ASP.NET内部实现,我们也设计一个IHttpHandler接口,只定义了一个方法:ProcessRequest;
3.4 设计实现IHttpHandler接口的HttpApplication类
public class HttpApplication : IHttpHandler
// 对请求上下文进行处理
public void ProcessRequest(HttpContext context)
// 1.获取网站根路径
string bastPath = AppDomain.CurrentDomain.BaseD
string fileName = Path.Combine(bastPath+"\\MyWebSite", context.Request.Url.TrimStart('/'));
string fileExtension = Path.GetExtension(context.Request.Url);
// 2.处理动态文件请求
if(fileExtension.Equals(".aspx") || fileExtension.Equals(".ashx"))
string className = Path.GetFileNameWithoutExtension(context.Request.Url);
IHttpHandler handler = Assembly.Load("MyWebServer").CreateInstance("MyWebServer.Page." + className) as IHttpH
handler.ProcessRequest(context);
// 3.处理静态文件请求
if (!File.Exists(fileName))
context.Response.StateCode = "404";
context.Response.StateDescription = "Not Found";
context.Response.ContentType = "text/html";
string notExistHtml = Path.Combine(bastPath, @"MyWebSite\notfound.html");
context.Response.Body = File.ReadAllBytes(notExistHtml);
context.Response.StateCode = "200";
context.Response.StateDescription = "OK";
context.Response.ContentType = GetContenType(Path.GetExtension(context.Request.Url));
context.Response.Body = File.ReadAllBytes(fileName);
// 根据文件扩展名获取内容类型
public string GetContenType(string fileExtension)
string type = "text/ charset=UTF-8";
switch (fileExtension)
case ".aspx":
case ".html":
case ".htm":
type = "text/ charset=UTF-8";
case ".png":
type = "image/png";
case ".gif":
type = "image/gif";
case ".jpg":
case ".jpeg":
type = "image/jpeg";
case ".css":
type = "text/css";
case ".js":
type = "application/x-javascript";
type = "text/ charset=gbk";
  这里,我们封装一个抽象的HttpApplication类,它实现了IHttpHandler接口,对一般的请求做一个通用的处理操作。如果是静态文件请求,则直接读取文件并生成响应流,如果是动态文件请求,则通过反射方式生成对应的Page对象实例,将HttpContext对象传入其ProcessRequest方法中进行处理,最后的响应内容都封装到了HttpConext中的HttpResponse对象的Body属性中。
3.5 设计实现IHttpHandler接口的模拟Page类
public class DemoPage : IHttpHandler
public void ProcessRequest(HttpContext context)
StringBuilder sbText = new StringBuilder();
sbText.Append("&html&");
sbText.Append("&head&&meta http-equiv='Content-Type' content='text/ charset=utf-8'/&&title&DemoPage&/title&&/head&");
sbText.Append("&body style='margin:10text-align:'&");
sbText.Append("&h1&用户信息列表&/h1&");
sbText.Append("&table align='center' cellpadding='1' cellspacing='1'&&thead&&tr&&td&ID&/td&&td&用户名&/td&&/tr&&/thead&");
sbText.Append("&tbody&");
sbText.Append(GetDataList());
sbText.Append("&/tbody&&/table&");
sbText.Append(string.Format("&h3&更新时间:{0}&/h3&", DateTime.Now.ToString()));
sbText.Append("&/body&");
sbText.Append("&/html&");
context.Response.Body = Encoding.UTF8.GetBytes(sbText.ToString());
context.Response.StateCode = "200";
context.Response.ContentType = "text/html";
context.Response.StateDescription = "OK";
private string GetDataList()
StringBuilder sbData = new StringBuilder();
string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["MyConn"].ToString();
using (SqlConnection conn = new SqlConnection(strConn))
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
cmd.CommandText = "SELECT * FROM UserInfo";
using(SqlDataAdapter adapter = new SqlDataAdapter(cmd))
DataTable dt = new DataTable();
adapter.Fill(dt);
if(dt != null)
foreach (DataRow row in dt.Rows)
sbData.Append("&tr&");
sbData.Append(string.Format("&td&{0}&/td&",row["ID"].ToString()));
sbData.Append(string.Format("&td&{0}&/td&", row["UserName"].ToString()));
sbData.Append("&/tr&");
return sbData.ToString();
  这里我们模拟一个Page页面类,它也实现了IHttpHandler接口,在ProcessRequest方法通过ADO.NET访问了数据库并读取数据作为输出内容。这里,我们主要是通过分析ASP.NET WebForm中的aspx对象,它虽然直接继承的类是Page类,但是Page类却是实现了IHttpHandler接口的。在具体的处理方法中,都是通过调用这个接口的ProcessRequest方法进行处理的。
四、个人开发小结
4.1 开发效果展示
  (1)开启监听服务
  (2)请求静态页面
  (3)请求动态页面
4.2 开发实战总结
  本次模拟的一个超级简单的Web服务器软件,实现了静态文件和动态文件(通过模拟aspx页面对象)的处理和响应。但是,还有很多的功能并未实现,因为一个真正的Web服务器需要考虑的东西很多很多,例如:多线程的处理优化、高效的IO模型等。不过,对于一个最基本的Web服务器所需要了解的最基本的原理:Socket的监听和连接、基于TCP协议的HTTP协议、动态文件类的反射与调用等,模拟开发本次的DEMO的过程是可以达到的。
  MyWebServer v1.0:
阅读(...) 评论()

我要回帖

更多关于 免费web服务器 的文章

 

随机推荐