数往知来 ASP.NET 模拟服务器:服务端_静态页面_动态页面的响应<十七>

时间:2023-03-08 16:21:06

 

数往知来  ASP.NET 模拟服务器:服务端_静态页面_动态页面的响应<十七>

数往知来  ASP.NET 模拟服务器:服务端_静态页面_动态页面的响应<十七>

数往知来  ASP.NET 模拟服务器:服务端_静态页面_动态页面的响应<十七>

一、客户端是怎么看到我们的网页的呢/

在浏览器端,如果用汉语请求的是一普通的HTML网页,呢么我们的IIS服务器,

接收到请求以后,那么从IIS服务器所在的电脑区查找该HTML网页,

找到以后将该HTML网页返回给我们的浏览器

如果客户端请求的是动态的网页(aspx/jsp等)我们的IIS处理不了,

它会找到映射表里找到这个文件所在的路径在这个文件夹下找到的对应的DLL文件,

然后把这个dll交给.net framawork来执行,

.net framawork会把执行之后产生的html代码返回给IIS服务器,

服务器再把这些HTML代码返回给浏览器

1:自己服务器_获取请求报文(委托的应用)

//主窗体中的代码

/// <summary>

        /// 开始服务器监听。

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        Socket ListenSocket = null;

        private void btn_Start_Click(object sender, EventArgs e)

        {

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

            IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text);

            IPEndPoint endpoint = new IPEndPoint(ipaddress,Convert.ToInt32(this.txtPort.Text));

            ListenSocket.Bind(endpoint);

            ListenSocket.Listen();

            Thread thread = new Thread(ServerConnection);

            thread.IsBackground = true;

            thread.Start();

        }

        public void ServerConnection()

        {

            while (true)

            {

                Socket newSocket = ListenSocket.Accept();//负责与浏览器进行通信的Socket.

                ShowMsg("链接成功"+newSocket.RemoteEndPoint.ToString());

                DataConnection connection = new DataConnection(newSocket, ShowMsg);

//将负责与浏览器交互的套接字传递的该类中,有该类完成对请求报文的接受与处理。

第二个参数,将用来显示请求报文的方法名作为参数传递该类中。

            }

        }

        /// <summary>

        /// 将请求报文追加到文本框中。

        /// </summary>

        /// <param name="msg"></param>

        public void ShowMsg(string msg)

        {

            this.txtContent.AppendText(msg+"\r\n");

        }

///DataConnection类中的代码

/// <summary>

    /// 对请求报文的接受与处理都是在该类中完成。

    /// 1:接收浏览器发送过来的请求报文。

    /// 2:将请求报文显示在文本框中

    /// 3:对请求报文进行分析。

    /// 4:对请求报文进行处理。

    /// 5:构建响应报文

    /// 6:将响应报文返回给浏览器。

    /// </summary>

    public class DataConnection

    {

        Socket newSocket = null;

        DGShowMsg DGShow = null;

        /// <summary>

        /// 第一参数:表示与浏览器进行交互的Socket.

        /// 二:是一个委托,那么将一个方法名赋给了改委托,那么接下来就可以使用该委托去调用该方法。

        /// </summary>

        /// <param name="newSocket"></param>

        /// <param name="DGShow"></param>

        public DataConnection(Socket newSocket, DGShowMsg DGShow)

       {

           this.newSocket = newSocket;//获取到了与客户端交互的套接字.

           this.DGShow = DGShow;

           Thread thread = new Thread(ReceiveMsg);

           thread.IsBackground = true;

           thread.Start();

       }

        /// <summary>

        /// 开始接受请求报文

        /// </summary>

       public void ReceiveMsg()

       {

           **];

           int receLength=newSocket.Receive(buffer);

//接收请求报文填充到buffer数组中,并且获得实际接收数据的长度.

           ,receLength);//转成字符串.

           DGShow(msg);//通过该委托调用了主窗体中的ShowMsg方法。

       }

public delegate void DGShowMsg(string msg);//我们自己定义的委托。

2:分析请求报文

HttpRequestModel类中代码

 /// <summary>

    /// 对请求报文进行分析处理的类

    /// </summary>

   public class HttpRequestModel

    {

       /// <summary>

       /// 将请求传递过来。

       /// </summary>

       /// <param name="msg"></param>

       public HttpRequestModel(string msg)

       {

           string[] arrayString=msg.Replace("\r\n", "罓").Split('罓');

//将"\r\n",替换成一个生僻词(字符),在根据该字符进行分割.

           ].Split(' ');//取出第一行,在根据空格进行分割.

           path=firstRow[].ToString();//获取到了请求报文中所要请求的文件的名称。

       }

       private string path;//请求报文中所要请求的文件.

       public string Path

       {

           get { return path; }

           set { path = value; }

       }

在DataConnection类中的ReceiveMsg方法新添加的代码

 HttpRequestModel requestModel = new HttpRequestModel(msg);

//将请求报文中的内容传递该类中进行处理。

3:对静态文件处理.

/// <summary>

        /// 开始对文件进行处理

        /// </summary>

        /// <param name="requestModel">该对象中包含了请求的文件名称</param>

       public void JustProcessPage(HttpRequestModel requestModel)

       {

           //1:看一下所请求的文件,在服务端是否存在.

           string Datadir = AppDomain.CurrentDomain.BaseDirectory;//获取.exe文件所在的目录.

           if (Datadir.EndsWith(@"\bin\Debug\") || Datadir.EndsWith(@"\bin\Release\"))

           {

               Datadir = System.IO.Directory.GetParent(Datadir).Parent.Parent.FullName;

//获取上一级目录的上一级.

           }

           string fullDir=Datadir + requestModel.Path;//在指定的目录下,去查找请求报文中的文件。

           //2:找到文件以后,判断该文件是静态文件还是动态文件.

           string extions=Path.GetExtension(requestModel.Path);//获取请求报文中所请求的文件的扩展名

           switch (extions)

           {

               case ".html":

               case ".htm":

                   ProcessStatePage(fullDir);//对获取到的静态的HTML文件进行处理。

(完整的所要访问的文件的路径)

                   break;

           }

       }

        /// <summary>

        /// 对静态文件进行处理.

        /// </summary>

        /// <param name="fullDir"></param>

       public void ProcessStatePage(string fullDir)

       {

           //由于是静态文件,所以在这里直接读取。

           byte[] buffer = null;

           using (FileStream fs = new FileStream(fullDir, FileMode.Open))

           {

               buffer=new byte[fs.Length];

               fs.Read(buffer, , buffer.Length);//直接将HTML代码(静态文件代码)读到buffer数组中.

               //构建响应报文。

               //响应体:buffer数组中存储的内容。

               //构建响应头.(调用HttpResponseModel中的方法构建响应头)

HttpResponseModel responseModel = new HttpResponseModel(buffer);//将buffer响应体传递到该类中。

               //将响应包文返回给浏览器

newSocket.Send(responseModel.GetHeaderResponse());

//获取在HttpResponseModel中定义的响应报文头,然后通过sokcet发给浏览器。

               //将响应报文体发送给浏览器

               newSocket.Send(buffer);

           }