IIS的内部原理

对IIS只有表面的理解   现在模拟一下IIS的内部原理:

View Code
 1         public int ServerScoket { get; set; }

 2         private void btnStart_Click(object sender, EventArgs e)

 3         {

 4             IPAddress ipAddress = IPAddress.Parse(this.txtIP.Text);

 5             IPEndPoint endpoint = new IPEndPoint(ipAddress, int.Parse(this.txtPort.Text));

 6             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 7             socket.Bind(endpoint);

 8             socket.Listen(10);

 9             this.lbStatus.Text = "启动";

10             this.lbStatus.ForeColor = Color.Green;

11             //开始socket的接受请求

12             ThreadPool.QueueUserWorkItem(a =>

13                 {

14                     //线程池默认都是后台线程

15                     Socket serverSocket = (Socket)a;

16                     while (true)

17                     {

18                         //获取到跟浏览器交互的代理socket

19                        var proxSocket= serverSocket.Accept();

20                         

21                        ThreadPool.QueueUserWorkItem(s => 

22                        {

23                            Socket pSocket = (Socket)s;

24                            byte[] bytes = new byte[1024 * 1024];

25                            int realLength = pSocket.Receive(bytes);

26                            //把当前的报文封装到了strRequest里面去了

27                            string strRequest = Encoding.UTF8.GetString(bytes, 0, realLength);

28                            //处理当前的报文,解析当前报文,看看请求是哪个文件,

29                            //把请求的文件封装成相应的报文,通过socket发送给浏览器

30                            ProcessRequest(strRequest, pSocket);

31                        }, proxSocket);

32                     }

33                 },socket);

34         }

35         //处理客户端的请求

36         private void ProcessRequest(string strRequest, Socket pSocket)

37         {

38             //把请求行取出来

39             //初始化请求信息和响应信息实例

40             HttpContext context = new HttpContext(strRequest);

41             HttpApplication application = new HttpApplication();

42 

43             //这时候,请求的响应已经做好了

44             //正在处理HTTP请求

45             application.ProcessRequest(context);

46 

47             //context response

48             pSocket.Send(context.Response.GetHeader());

49             pSocket.Send(context.Response.BodyData);

50             pSocket.Shutdown(SocketShutdown.Both);

51             pSocket.Close();

52         }

HttpContext封装上下文

  public   class HttpContext

    {

      //设置请求

      public HttpRequest Request { get; set; }

      //响应的实例

      public HttpResponse Response { get; set; }

      //构造函数

      public HttpContext(string httpRequestStr)

      {

          Request = new HttpRequest(httpRequestStr);

          Response = new HttpResponse(Request);

      }

    }

HttpRequest对象:

 1     /// <summary>

 2     /// 封装请求报文的信息

 3     /// </summary>

 4   public  class HttpRequest

 5     {

 6         /*

 7          GET /login.aspx HTTP/1.1

 8         Accept: text/html, application/xhtml+xml, #1#*

 9         Accept-Language: zh-CN

10         User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; QDesk 2.3.1185.202; Windows NT 6.1; Trident/5.0)

11         Accept-Encoding: gzip, deflate

12         Host: localhost:38888

13         Connection: Keep-Alive*/

14 

15       //将报文传进来

16       public HttpRequest(string requestStr)

17       {

18           if(!string.IsNullOrEmpty(requestStr))

19           {

20             string[] lines=requestStr.Replace("\r\n","\r").Split('\r');

21               //处理请求的Method

22             this.Method = lines[0].Split(' ')[0];

23               //设置请求的URL 地址

24             this.RequestURL = lines[0].Split(' ')[1];

25           }

26       }

27       //是Get 还是set

28       public string  Method { get; set; }

29       public string  RequestURL { get; set; }

30     }

HttpResponse

View Code
 1   public class HttpResponse

 2     {

 3        //请求文件的后缀

 4        private string _requestFileExt;

 5        public HttpResponse(HttpRequest request)

 6        {

 7            _requestFileExt = Path.GetExtension(request.RequestURL);

 8        }

 9        //获取相应提报文字节数组

10        public byte[] BodyData { get; set; }

11        //获取响应头部

12        public byte[] GetHeader()

13        {

14            StringBuilder sb = new StringBuilder();

15            sb.AppendFormat("HTTP/1.1 200 OK\r\n");

16            sb.AppendFormat("Content-Type: {0} \r\n", GetContentType(_requestFileExt));

17            return Encoding.UTF8.GetBytes(sb.ToString());

18        }

19 

20        public string GetContentType(string _requestFileExt)

21        {

22            string type = "text/html";

23            switch (_requestFileExt)

24            {

25                case ".aspx":

26                    case ".html":

27                 case ".htm":

28                     type = "text/html";

29                     break;

30                 case ".png":

31                     type = "image/png";

32                     break;

33                 case ".gif":

34                     type = "image/gif";

35                     break;

36                 case ".jpg":

37                 case ".jpeg":

38                     type = "image/jpeg";

39                     break;

40                 case ".css":

41                     type = "text/css";

42                     break;

43                 case ".js":

44                     type = "application/x-javascript";

45                     break;

46                 default:

47                     type = "text/plain";

48                     break;

49            }

50            return type;

51        }

52 

53        //返回响应主体

54        public byte[] GetBodyData()

55        {

56            return BodyData;

57        }

58     }

HttpApplication 中处理

 1    public  class HttpApplication

 2     { public void ProcessRequest(HttpContext context)

 3        {

 4            string ext = Path.GetExtension(context.Request.RequestURL);

 5            switch (ext)

 6            {

 7                case ".jpg":

 8                case ".jpeg":

 9                case ".html":

10                case ".htm":

11                case ".css":

12                case ".js":

13                    ProcessStaticFile(context); break;

14                case ".aspx":

15                    ProcessDynamicFile(context);

16                    break;

17                default:

18                    ProcessStaticFile(context);

19                    break;

20            }

21        }

22        //处理动态页面

23        public void ProcessDynamicFile(HttpContext context)

24        {

25            //假设请求Index.aspx

26            string className=Path.GetFileNameWithoutExtension(context.Request.RequestURL);

27            //获取命名空间

28            string nameSpace = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;

29            //_02HeimaIIS.IndexPage

30            string fullName = nameSpace + "." + className;

31            //用接口接受不同的实例

32            IHttpHandler obj=(IHttpHandler)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(fullName,true);

33            if (obj == null)

34            {

35 

36            }

37            else

38            {

39                obj.ProcessRequest(context);

40            }

41        }

42        //处理静态页面

43        public void ProcessStaticFile(HttpContext context)

44        {

45            string currentWebDir = AppDomain.CurrentDomain.BaseDirectory;

46            string fileName=Path.Combine(currentWebDir,context.Request.RequestURL.TrimStart('/'));

47            context.Response.BodyData = File.ReadAllBytes(fileName);

48        }

49     }

如果是静态网页直接返回

如果是动态页面通过反射实现

以上就是面向接口编程

1     public class MyPage : IHttpHandler

2     {

3         public void ProcessRequest(HttpContext context)

4         {

5             //可以访问数据库,就是动态的

6             string strBody = @"<html><head></head><body><h2> big shit y</h2></body></html>";

7             context.Response.BodyData = Encoding.UTF8.GetBytes(strBody);

8         }      

9     }

 

 IIS内部处理的文字总结:

 设置一个监听队列,用一个应用程序池中的实例socket A,接受浏览器发送的数据,再从应用程序池中获取一个实例 socket B将接受到的数据进行处理,而 socket A 不断接受浏览器的请求。

socket B处理数据(用到HttpContext HttpApplication MyPage IHandler)

HttpContext

  HttpRequest 获取请求的方法 及请求的地址

  HttpResponse得到响应体和 响应头

HttpApplication

  根据后缀名判断是动态网页还是静态网页

  动态网页:通过反射获取命名空间  通过请求地址找到类名  通过反射获取实例转化成接口,调用其方法。

处理完成后,由代理socket发送报文头和报文体

  

 

 

你可能感兴趣的:(IIS)