自定义web服务器(四)

   关于HTTP协议的具体内容,前面章节已经有所讲解,相信读者已有所了解,在此不在累述,本章节讲解自定义web服务器。

 一,.net提供自定义Web服务器的类

      以下只是写主要的类

      1.HTTPListener:对TCPListener的封装

      2.TCPListener:对Socket的封装

      3.Socket:对协议栈传输层接口的封装

 二,用.net提供的类进行web服务器的自定义

     1.用HTTPListener

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Globalization;
using System.Threading;

namespace Microsoft.Samples.HttpListener
{
    static class HttpRequestListener
    {
        public static void Main()
        {
            string[] prefixes = new string[1];
            prefixes[0] = "http://localhost:8080/";
            ProcessRequests(prefixes);
        }


        private static void ProcessRequests(string[] prefixes)
        {
            if (!System.Net.HttpListener.IsSupported)
            {
                Console.WriteLine(
                    "Windows XP SP2, Server 2003, or higher is required to " +
                    "use the HttpListener class.");
                return;
            }
            // URI prefixes are required,
            if (prefixes == null || prefixes.Length == 0)
                throw new ArgumentException("prefixes");

            // Create a listener and add the prefixes.
            System.Net.HttpListener listener = new System.Net.HttpListener();
            Thread handleRequest = null;
            foreach (string s in prefixes)
            {
                listener.Prefixes.Add(s);
            }

            try
            {
                // 启动监听,开始监听请求
                listener.Start();
                Console.WriteLine("Listening...");

              while(true)
              {
                    HttpListenerResponse response = null;
                    
                        //  GetContext 在等待一个请求时将阻塞 .
                        HttpListenerContext context = listener.GetContext();

                       
                        handleRequest = new Thread(delegate()
                        {
                            try
                            {
                                Console.WriteLine("当前线程是否为线程池线程:" + (Thread.CurrentThread.IsThreadPoolThread==true?"":""));
                               Console.WriteLine("当前线程总数:" + System.Diagnostics.Process.GetCurrentProcess().Threads.Count.ToString());
                            response = context.Response;

                            string responseBody =
                                "<HTML><head><script language='javascript' type='text/javascript'>function test(){alert('你好');}</script></head><BODY><form>The time is currently " + DateTime.Now.ToString() + "<br/>";
                            responseBody += "<input type='button' value='js测试' id='test1' onclick='test();'/><br/><input type='submit' value='提交测试' id='test2' /></form></BODY></HTML>";
                            string responseHeader =
                         string.Format(
                             "Content-Type: text/html; charset=UTf-8;Content-Length: {0}", responseBody.Length);

                            byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);
                            response.ContentLength64 = responseBodyBytes.Length;
                            System.IO.Stream output = response.OutputStream;
                            // 向客户端发送回应头信息
                            response.Headers.Add(responseHeader);
                            // 向客户端发送状态行
                            response.StatusCode = (int)HttpStatusCode.OK;
                            response.ProtocolVersion = Version.Parse("1.1");
                            // 想客户端发送主体部分
                            output.Write(responseBodyBytes, 0, responseBodyBytes.Length);
                            }
                            catch (HttpListenerException ex)
                            {
                               Console.WriteLine(ex.Message);
                             }
                            finally
                            {
                              if (response != null)
                                response.Close();
                            }
                            Thread.Sleep(100000);
                        });
                        handleRequest.Start();
                    }
            }
            catch (HttpListenerException ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                //停止监听
                listener.Close();
                Console.WriteLine("Done Listening.");
            }
        }
    }
}
View Code

         服务端运行效果:

        

         客户端运行效果:

        

     2.用TCPListener

  private static void  ProcessRequestsWithTcpListener()
       {
           TcpListener server=new TcpListener(IPAddress.Any,8081);
       
           server.Start();

           Console.WriteLine("HTTP Server Start Listening....");

           while (true)
           {
               TcpClient client = server.AcceptTcpClient();
               Thread handleRequest = new Thread(delegate()
               {
                   try
                   {
                       NetworkStream inputoutputstream = client.GetStream();
                       Byte[] buffer = new Byte[1024];
                       int readLength = inputoutputstream.Read(buffer, 0, buffer.Length);
                       String inputoutputstring = Encoding.ASCII.GetString(buffer, 0, readLength);

                       Console.WriteLine("客户端信息:" + client.Client.RemoteEndPoint);
                       Console.WriteLine("客户端请求信息:
" + inputoutputstring);

                       String statusLine = "HTTP/1.1 200 OK
";
                       string responseBody =
                                   "<HTML><head><script language='javascript' type='text/javascript'>function test(){alert('你好');}</script></head><BODY><form>The time is currently " + DateTime.Now.ToString() + "<br/>";
                       responseBody += "<input type='button' value='js测试' id='test1' onclick='test();'/><br/><input type='submit' value='提交测试' id='test2' /></form></BODY></HTML>";
                       string responseHeader =
                           string.Format(
                               "Content-Type: text/html; charset=UTf-8
Content-Length: {0}
", responseBody.Length + statusLine.Length);
                       byte[] responseStatusLineBytes = Encoding.UTF8.GetBytes(statusLine);
                       byte[] responseHeaderBytes = Encoding.UTF8.GetBytes(responseHeader);
                       byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);

                       // 写入状态行信息
                       inputoutputstream.Write(responseStatusLineBytes, 0, responseStatusLineBytes.Length);
                       // 写入回应的头部
                       inputoutputstream.Write(responseHeaderBytes, 0, responseHeaderBytes.Length);
                       // 写入回应头部和内容之间的空行
                       inputoutputstream.Write(new byte[] { 13, 10 }, 0, 2);

                       // 写入回应的内容
                       inputoutputstream.Write(responseBodyBytes, 0, responseBodyBytes.Length);
                   }
                   catch (Exception ex)
                   {
                       Console.WriteLine("异常信息:"+ex.Message);
                   }
                   finally
                   {
                       // 关闭与客户端的连接
                       client.Close();
                   }

               });
               handleRequest.Start();
           }
       }
View Code

        服务端运行效果:

     

        客户端运行效果:和1类似

      3.用Socket

 private static void ProcessRequestsWithSocket()
        {
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Bind(new IPEndPoint(IPAddress.Any, 8082));
            server.Listen(100);

            Console.WriteLine("HTTP Server Start Listening....");

            while (true)
            {
                Socket client = server.Accept();
                Thread handleRequest = new Thread(delegate()
                {
                    try
                    {
                        Byte[] buffer = new Byte[1024];
                        int readLength = client.Receive(buffer, buffer.Length,SocketFlags.None);
                        String inputoutputstring = Encoding.ASCII.GetString(buffer, 0, readLength);

                        Console.WriteLine("客户端信息:" + client.RemoteEndPoint);
                        Console.WriteLine("客户端请求信息:
" + inputoutputstring);

                        String statusLine = "HTTP/1.1 200 OK
";
                        string responseBody =
                                    "<HTML><head><script language='javascript' type='text/javascript'>function test(){alert('你好');}</script></head><BODY><form>The time is currently " + DateTime.Now.ToString() + "<br/>";
                        responseBody += "<input type='button' value='js测试' id='test1' onclick='test();'/><br/><input type='submit' value='提交测试' id='test2' /></form></BODY></HTML>";
                        string responseHeader =
                            string.Format(
                                "Content-Type: text/html; charset=UTf-8
Content-Length: {0}
", responseBody.Length + statusLine.Length);
                        byte[] responseStatusLineBytes = Encoding.UTF8.GetBytes(statusLine);
                        byte[] responseHeaderBytes = Encoding.UTF8.GetBytes(responseHeader);
                        byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);

                        // 写入状态行信息
                        client.Send(responseStatusLineBytes);
                        // 写入回应的头部
                        client.Send(responseHeaderBytes);
                        // 写入回应头部和内容之间的空行
                        client.Send(new byte[] { 13, 10 });

                        // 写入回应的内容
                        client.Send(responseBodyBytes);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("异常信息:" + ex.Message);
                    }
                    finally
                    {
                        // 关闭与客户端的连接
                        client.Close();
                    }

                });
                handleRequest.Start();
            }
        }
View Code

        服务端和客户端运行效果和2类似.
    声明:2和3代码修改自:http://www.cnblogs.com/zhili/archive/2012/08/23/WebServer.html 只为交流,不为商用.

    备注:面试时,常问的一个问题是:http中post和get请求的区别

            个人感觉:1.两者传输方式不同,post将数据放在请求内容里传输,get放在请求行传输

                          2.post内容没有大小限制,get内容有大小限制。

原文地址:https://www.cnblogs.com/liangjie/p/3154486.html