自定义简易web服务器

我们都知道web网站一般都有一个宿主来运行,比如IIS,,Apache...

 

那么我们自己能不能做一个宿主来运行web网站呢?

 

肯定是可以的,今天我们用socket来做一个,当然这里是用C#来做演示

 

 

 

首先定义这么几个东西,,两个html页面

 

 

 

 

//引入空间
using System.Net;
using System.Net.Sockets;

   /// <summary>
    /// web服务启动器
    /// </summary>
 public    class WebServer
    {
        //定义一个Socket
        private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        //启动服务器
        public static void Start()
        {
            socket.Bind(new IPEndPoint(IPAddress.Any, 8002));
            socket.Listen(10);

            //接收客户端Scoket请求:  public delegate void AsyncCallback(IAsyncResult ar)
            socket.BeginAccept(OnAccept, socket);

            Console.WriteLine("web服务器成功启动!");

        }
        //接收请求(回调函数)
        public static void OnAccept(IAsyncResult result)
        {

            //服务器端的Scoket
            Socket serverScoket = result.AsyncState as Socket;

            //客户端的Scoket
            var clientScoket = serverScoket.EndAccept(result);

            //继续异步监听
            serverScoket.BeginAccept(OnAccept, serverScoket);

            //获取Scoket内容
            var dataBytes = new byte[10000];
            var dataLenth = clientScoket.Receive(dataBytes);

            //将bytes[]数组转化成字符串
            var requestData = Encoding.UTF8.GetString(dataBytes, 0, dataLenth);

            //返回的数据
            var responseData = string.Empty;

            //获取请求文件的路径(但是这个路径就是根目录,所以,我们只要得到文件名就行)
            // GET / test1.html HTTP / 1.1\r\nHost: 127.0.0.1:8002\r\n

            if (!string.IsNullOrEmpty(requestData) && !requestData.Contains("favicon.ico"))
            {
                var filePath = requestData.Split("\r\n")[0].Split(" ")[1].TrimStart('/');

                //读取内容
                if (System.IO.File.Exists(filePath))
                    responseData = System.IO.File.ReadAllText(filePath, Encoding.UTF8);
                else
                    responseData = "404 not found";
            }


            //我们再按照HTTP响应报文的要求返回数据(可以做成一个模板)
            var responseHeader = $@"  HTTP/2.0 200 OK
                                    date: Thu, 13 Jun 2020 13:33:11 GMT
                                    content-type: text/html; charset=utf-8
                                    content-length:  { Encoding.UTF8.GetByteCount(responseData)}
                                    server: nginx
                                    x-server: tencent64.site
                                    x-request-id: 593e1542-e7e4-419c-b48e-fa90b4991df8
                                    x-client-proto: http
                                    x-client-proto-ver: HTTP/2.0
                                    X-Firefox-Spdy: h2";

            //将响应头传输给客户
            clientScoket.Send(Encoding.UTF8.GetBytes(responseHeader));
            //将响应主体传输给客户端
            clientScoket.Send(Encoding.UTF8.GetBytes(responseData));

            //关闭
            clientScoket.Close();
        }
    }

  

运行程序

 

 

 

 

 

posted @ 2021-01-07 20:34  wrjhzou  阅读(238)  评论(0)    收藏  举报