• 自定义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内容有大小限制。

  • 相关阅读:
    MFC中添加自己定义的消息
    动态创建的list control添加消息响应
    关于CString的奇怪问题
    如何去掉按钮在输入焦点切换时所产生的闪烁
    wince中将自己的应用程序编译到内核并开机启动的一种方法
    wince下圆角矩形按钮的实现
    关于error C2471:无法更新程序数据库的错误的解决方法
    关于烧写开机logo之后导致无法启动系统的问题
    利用IdHTTP进行多线程下载
    TEdit 控件的提示,就像 IE7 的地址输入栏一样
  • 原文地址:https://www.cnblogs.com/liangjie/p/3154486.html
Copyright © 2020-2023  润新知