zoukankan      html  css  js  c++  java
  • 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发送报文头和报文体

      

  • 相关阅读:
    jQuery 元素操作
    jQuery 文本属性值
    jQuery 属性操作
    jQuery 效果
    sass入门学习篇(二)
    sass入门学习篇(一)
    CSS3 基础知识[转载minsong的博客]
    js倒计时,秒倒计时,天倒计时
    webstorm快捷键收集【转发】
    placeholder各种浏览器兼容问题
  • 原文地址:https://www.cnblogs.com/cheshui/p/2704642.html
Copyright © 2011-2022 走看看