用Socket来简单实现IIS服务器

刚刚接触ASP.NET编程,为了更好的屡清楚服务器的处理过程,就用Socket模拟服务器来处理请求。用Socket来模拟服务器的时候,同样是自己来封装一些对应的类文件。包括 HttpRequest、HttpResponse、HttpContext、HttpApplication、IHttpHandel。主要的执行流程是:先用Socket来创建一个简单的服务器,进行监听,当监听到请求后将请求交给处理程序去处理,应用程序中根据请求的是静态资源还是动态资源做出不同的处理。然后通过Socket对象将响应类容给发送回去。这只是为了更好的了解服务器的处理,进行了一个简单的模拟,程序中有很多的bug,但是能够实现基本的功能

HttpRequest类

主要包含几个主要的属性:请求方式,请求地址,请求协议的版本号

 1     public class HttpRequest
 2     {
 3         public HttpRequest (string str)
 4         {
 5             if (string.IsNullOrEmpty(str))
 6             {
 7                 return;
 8             }
 9             string head = str.Replace("\r\n", "$").Split(‘$‘)[0];
10             string[] heads = head.Split(‘ ‘);
11             Method = heads.Length>1? heads[0]:"";
12             //得到请求的绝对路径
13             Url = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), heads.Length>1? heads[1].Substring(1):heads[0]);
14             Protocol = heads.Length > 1 ? heads[2] : "";
15
16         }
17
18         public string Method { get; set; }
19         public string Url { get; set; }
20         public string Protocol { get; set; }
21     }

HttpRequest类

HttpResponse类

包含响应头和响应体,在网络上传输的是二进制文件,故将这两个属性定义为byte[],中间还包含其他的一些属性。其中响应长度是动态的,在处理程序里面设置

 1     public class HttpResponse
 2     {
 3         public HttpResponse (HttpRequest request)
 4         {
 5             this.request = request;
 6             Type = GetType(Path.GetExtension(request.Url));
 7         }
 8
 9         private HttpRequest request;
10         private string Type { get; set; }
11         public int Length { get; set; }
12         public byte[] Head {
13             get
14             {
15
16                 //                -----响应报文------------
17                 //HTTP/1.1 200 OK
18                 //Connection: keep-alive
19                 //Date: Thu, 26 Jul 2007 14:00:02 GMT
20                 //Server: Microsoft-IIS/6.0
21                 //X-Powered-By: ASP.NET
22                 //Content-Length: 190
23                 //Content-Type: text/html
24                 //Set-Cookie: ASPSESSIONIDSAATTCSQ=JOPPKDCAMHHBEOICJPGPBJOB; path=/
25                 //Cache-control: private
26                 ////--空行--
27                 //响应体(正文)
28
29                 StringBuilder sb = new StringBuilder();
30                 sb.AppendFormat("{0} {1}\r\n", request.Protocol, "200 OK");
31                 sb.AppendLine("Date:" + DateTime.Now.ToString());
32                 sb.AppendLine("Server:QIGANG-PC");
33                 sb.AppendLine("Content-Length:" + Length);
34                 sb.AppendLine("Content-Type:" + Type);
35                 sb.AppendLine();
36                 return Encoding.UTF8.GetBytes(sb.ToString());
37
38
39             }
40         }
41         public byte[] Body { get; set; }
42
43     ///根据请求来得到响应的类型
44         private string GetType (string ext)
45         {
46             string type1 = "text/html;charset=utf-8";
47             switch (ext)//mime-type
48             {
49                 case ".aspx":
50                 case ".html":
51                 case ".htm":
52                     type1 = "text/html;charset=utf-8";
53                     break;
54                 case ".png":
55                     type1 = "image/png";
56                     break;
57                 case ".gif":
58                     type1 = "image/gif";
59                     break;
60                 case ".jpg":
61                 case ".jpeg":
62                     type1 = "image/jpeg";
63                     break;
64                 case ".css":
65                     type1 = "text/css";
66                     break;
67                 case ".js":
68                     type1 = "application/x-javascript";
69                     break;
70                 default:
71                     type1 = "text/plain;charset=gbk";
72                     break;
73             }
74             return type1;
75         }
76     }

HttpResponse类

HttpContext类

在这个类里面简单的封装了两个成员对象,就是HttpRequest和HttpResponse两个成员,其它的就从简了

 1     public class HttpContext
 2     {
 3         public HttpContext (string str)
 4         {
 5             Request = new HttpRequest(str);
 6             Response = new HttpResponse(Request);
 7         }
 8         public HttpRequest Request { get; set; }
 9         public HttpResponse Response { get; set; }
10     }

HttpContext类

IHttpHandel接口

由于在客户端请求的数据中可能请求的是一个动态网页,这是就需要交给.NET Framework 来进行处理,为了方便处理,故要求所有的动态网页都需要实现一个接口,只有实现了这个接口的程序才能够被浏览器给请求到

1     public interface IHttpHandel
2     {
3         void ProcessRequest (HttpContext context);
4     }

IHttpHandel接口

服务器端Socket程序

在这主要是启动一个Socket对象,来进行连接的监听,然后把监听到的对象交给处理程序 HttpApplication进行处理

 1         private void button1_Click (object sender, EventArgs e)
 2         {
 3             socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 4             socket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 22822));
 5             socket.Listen(10);
 6             Thread thread = new Thread((obj) =>
 7             {
 8                 Socket server = obj as Socket;
 9                 while (true)
10                 {
11                     Socket client = server.Accept();
12                     Thread cth = new Thread((obj2) =>
13                     {
14                         Socket cSocket = obj2 as Socket;
15
16                         byte[] by = new byte[cSocket.Available];
17                         cSocket.Receive(by, 0, by.Length, SocketFlags.None);
18             //拿到请求头文件
19                         string str = Encoding.UTF8.GetString(by);
20
21                         /*--------- 调用请求处理函数进行处理 ---------*/
22                         HttpContext context = new HttpContext(str);
23                         HttpApplication app = new HttpApplication(context, cSocket);
24                     });
25                     cth.IsBackground = true;
26                     cth.Start(client);
27                 }
28             });
29             thread.IsBackground = true;
30             thread.Start(socket);
31         }

Socket服务端程序

HttpApplication类

这个类需要传递一个参数,上下文对象。然后进行请求的解析,根据请求的是静态资源还是动态资源去进行不同的处理。如果是静态资源就直接冲磁盘文件中读取返回,如果是动态资源,就交给对应的类。当然前提是请求的资源名称就对应了一个类文件。

 1     public class HttpApplication
 2     {
 3     //构造函数
 4         public HttpApplication (HttpContext context,Socket socket)
 5         {
 6             string url =context.Request.Url;
 7             if(string.IsNullOrEmpty(url)){
 8                 return;
 9             }
10             string ext = Path.GetExtension(url);
11         //请求的是动态资源文件
12             if (ext == ".aspx")
13             {
14         //下面的代码中也就没有进行错误的处理了,主要是模拟,没有考虑其他的情况
15         //拿到请求资源的文件名(不包含后缀)
16                 string cs = Path.GetFileNameWithoutExtension(url);
17         //得到当前程序的程序集
18                 Assembly ass = Assembly.GetExecutingAssembly();
19         //拿到请求的文件对应的类
20                 Type type = ass.GetType(ass.GetName().Name + "." + cs, true, true);
21         //创建对象,进行调用
22                 IHttpHandel handel = Activator.CreateInstance(type) as IHttpHandel;
23                 handel.ProcessRequest(context);
24         //上面几句话可以合并到一起,拿到程序集后直接CreateInstance();
25             }
26             else if (ext == ".ashx")
27             {
28             }
29             else//访问静态资源
30             {
31                //直接从磁盘中读取请求的资源文件
32                 byte[] by = File.ReadAllBytes(url);
33                 context.Response.Length = by.Length;
34                 context.Response.Body = by;
35
36             }
37             socket.Send(context.Response.Head);
38             socket.Send(context.Response.Body);
39         }
40     }

HttpApplication类

整个请求的模型基本上就差不多完成了,如果是请求的动态文件b.aspx,那么这个b.cs文件需要实现IHttpHandel接口,同时在规定的方法里面进行处理,代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7
 8 namespace IIS_Two
 9 {
10     public class b:IHttpHandel
11
12     {
13         public void ProcessRequest (HttpContext context)
14         {
15         //读取模板HTML文件
16             string html = File.ReadAllText("temp.html");
17             string temp = "<table border=‘1‘>{0}</table>";
18         //读取文本文件类容,拼接一个table表格
19             using (StreamReader reader = new StreamReader("1.txt"))
20             {
21                 string str = "";
22                 List<string> list = new List<string>();
23                 while ((str = reader.ReadLine()) != null)
24                 {
25                     string[] strs = str.Split(‘:‘);
26                     list.Add("<tr><td>" + strs[0] + "</td><td>" + strs[1] + "</td></tr>");
27
28                 }
29                 temp = string.Format(temp, string.Join("", list));
30             }
31         //模板内容的替换
32             html = html.Replace("$body", temp);
33             byte[] by = Encoding.UTF8.GetBytes(html);
34             context.Response.Length = by.Length;
35             context.Response.Body = by;
36         }
37     }
38 }

b.cs文件,对应b.aspx资源

附上b.cs中用到的一个HTML模板和一个txt文件

 1 <!DOCTYPE html>
 2
 3 <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 4 <head>
 5     <meta charset="utf-8" />
 6     <title></title>
 7 </head>
 8 <body>
 9     $body
10 </body>
11 </html>

temp.html

1 aaa:22
2 bbb:23
3 ccc:18

1.txt

整个简单的模拟就完成了,bug很多,这不重要。如果请求一个简单的html页面或者是jpg等图片都能够成功,当然这些文件要存在代码中所写的目录下面才行

用Socket来简单实现IIS服务器,布布扣,bubuko.com

时间: 2024-10-14 04:11:51

用Socket来简单实现IIS服务器的相关文章

Java网络学习笔记1:用(Server)Socket编写简单的客户/服务器程序

首先需清楚Socket类提供了getInputStream()方法和getOutputStream()方法,分别返回输入流InputStream对象和输出流OutputStream对象.程序只需向数据流写数据,就能向对方发送数据:只需从输入流读数据,就能接收来自对方的数据. 创建服务器程序DemoServer01 public class DemoServer01 { /**  * @author 牧羊的伯格女皇  11/12  * @param args  * 创建服务端与客户端之间的相互通信

第27篇 重复造轮子---模拟IIS服务器

在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西是一个更好的理解和使用.   当你打开一个网页时,你会看到一个html页面的呈现,当然这是一个完整的Http的请求和响应的过程,无非是对HTML+CSS+JS一个综合的产物,在这个过程中浏览器请求数据的过程中会发出一个有一个格式的字符串(基于http协议生成的http请求报文),服务器在接收这样的一

C#中使用Socket实现简单Web服务器

原文地址:https://www.cnblogs.com/mq0036/p/6656888.html 最近有个web的小项目,但公司的电脑无法安装IIS,所以就想自己来实现个Web server服务器,原本想了下,也就是socket处理http请求,于是就在博客园中搜索了"socket实现web server",结果还真搜索到一些文章,于是从中找了几个做参考,如下: C#中使用Socket实现简单Web服务器 C#中使用Socket模拟请求Web服务器过程 C#中自己动手创建一个Web

运用socket实现简单的服务器客户端交互

Socket解释: 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务.Socket正如其英文原意

Socket实现简单Web服务器

上一篇博客中介绍了怎样使用socket访问web服务器.关键有两个: 1)熟悉Socket编程: 2)熟悉HTTP协议. 上一篇主要是通过socket来模拟浏览器向(任何)Web服务器发送(HTTP)请求,重点在浏览器端.本篇博客则反过来讲一下怎样使用socket来实现Web服务器,怎样去接收.分析.处理最后回复来自浏览器的HTTP请求. HTTP协议是浏览器和Web服务器都需要遵守的一种通信规范,如果我们编写一个程序,正确遵守了HTTP协议,那么理论上讲,这个程序可以具备浏览器.甚至Web服务

用Python socket实现一个简单的http服务器(post 与get 的区别)

预备知识: 关于http协议的基础请参考这里. 关于socket基础函数请参考这里. 关于python网络编程基础请参考这里. 废话不多说,前面实现过使用linux c 或者python 充当客户端来获取http 响应,也利用muduo库实现过一个简易http服务器,现在来实现一个python版的简易http服务器,代码改编自http://www.cnblogs.com/vamei/ httpServer.py Python Code 1 2 3 4 5 6 7 8 9 10 11 12 13

(转)C# Socket简单例子(服务器与客户端通信)

本文转载自:http://blog.csdn.net/andrew_wx/article/details/6629721 这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消息边界问题.端口号是否被占用.消息命令的解析问题等.. 下面是两个程序的代码,(两个程序均为控制台程序) 先发服务端的(Server)完整代码如下: 引入命名空间: [cshar

[python网络编程]利用socket编写简单的服务器

利用socket编写简单的服务器 步骤解析 建立socket对象 这一步跟我们上次使用socket做客户端是一样的,都需要有一个socket连接 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 设置socket选项(setsockopt) 选项介绍setsockopt(set socket option),参数设置格式:setsockopt(level,optname,value) 各选项的关系:1.level:level的设定决定了op

Java Socket编程(五) 简单的WEB服务器

简单的WEB服务器 一个简单的WEB服务器将由列表9.2这样构建.当然,还必须要对方法和回应事件进行改进.简单的服务器不会分析和存储请求头.新的WEB服务器将分析和存储请求,为以后的处理作准备.为了达到这个目的,你必须有一个包含HTTP请求的类. HTTPrequest类 列表9.5列出了一个完整的HTTPrequest类.这个类必须包括一个请求头所需的所有信息. 列表9.5.HTTPrequest类. import java.io.*; import java.util.*; import j