自定义轻量级的HTTP WebServer (WEB服务器)

一直觉得网站www.studyez.com 处理静态文件不怎么快,就想能不能把这些静态文件单独放在另外一台服务器(StaticFileServer)上面。让主服务器只处理.aspx文件即可。StaticFileServer只负责输出静态文件,减轻主服务器的压力。远景的想法是把它用C/C++改写。

不过,发现用C/C++哪是相当的麻烦,而且也没有必要。反正就是自己用用。先搭个架子先吧。

对于以后的GET请求的分析,稍后在发上来。网上找的一些基上都是把接收到byte[]转化成字符串然后来分析,

个人觉得这种做法效率不怎么好。不过目前也没想到什么好法子。特别对于POST请求的分析。

下面涉及到异步回调《AsyncCallback》,Socket 等东西。好记性不如烂笔头,还是记下先吧。

 

下面是源代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.Cache;
using System.IO;


namespace WinSocket
{
    public class HttpSocket
    {
        static System.Threading.AutoResetEvent a = new System.Threading.AutoResetEvent(true);
        static void Main(string[] args)
        {
            IPHostEntry en = Dns.GetHostEntry("127.0.0.1");
            IPAddress ipAddr = en.AddressList[0];

            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Bind(new IPEndPoint(ipAddr, 10000));
            server.Listen(1000);
            try
            {
                while (true)
                {
                    a.Reset();
                    Console.WriteLine("Waiting for a connection...");
                    server.BeginAccept(new AsyncCallback(AcceptReceiveDataCallback), server);

                     //int receivedDataSize = 1024;
                     //server.BeginAccept(receivedDataSize, new AsyncCallback(AcceptReceiveDataCallback), server);

                   // Wait until a connection is made and processed before continuing.
                    a.WaitOne();
   
                }
            }
            finally
            {
                server.Shutdown(SocketShutdown.Both);
                server.Close();
            }

        }

        static void AcceptReceiveDataCallback(IAsyncResult ar)
        {
            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);
            //byte[] Buffer;
            //int bytesTransferred;
            //Socket handler = listener.EndAccept(out Buffer, out bytesTransferred, ar);
            a.Set();
            //string stringTransferred = Encoding.ASCII.GetString(Buffer, 0, bytesTransferred);
            //Console.WriteLine(stringTransferred);
            //Console.WriteLine("Size of data transferred is {0}", bytesTransferred);

            ReceiveStateObject state = new ReceiveStateObject(handler, 1024);

            handler.BeginReceive(state.Buffer, 0, state.BufferSize, SocketFlags.None,  new AsyncCallback(ReadCallback), state);
        }
        static void ReadCallback(IAsyncResult ar)
        {
       
            ReceiveStateObject state = (ReceiveStateObject)ar.AsyncState;
            Socket handler = state.WorkerSocket;
            int read = handler.EndReceive(ar);
            if (read > 0 && read ==state.BufferSize )
            {
                //继续读取
                handler.BeginReceive(state.Buffer, 0, state.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
            }
            else
            {
                //处理结束
                //读取结束
                StringBuilder _sb = new StringBuilder();
                FileInfo fi = new FileInfo(@"H:/HttpWebServer/index.html");
                _sb.AppendLine("HTTP/1.0 200 OK");
                _sb.AppendLine("MIME-version:1.0");
                _sb.AppendLine("Content-type:text/html");
                _sb.AppendLine("Content-length:" + fi.Length.ToString());
                _sb.AppendLine();
                byte[] c = System.Text.Encoding.Default.GetBytes(_sb.ToString());
                handler.BeginSend(c, 0, c.Length, SocketFlags.None, new AsyncCallback(SendCallback), new ResponseStateObject(handler, c.Length));
            }


        }
        static void SendCallback(IAsyncResult ar)
        {
            ResponseStateObject res = (ResponseStateObject)ar.AsyncState;
            Socket handler = res.WorkerSocket;
            int c = handler.EndSend(ar);
            if (c != res.Len)
            {
                Console.WriteLine("数据尚未正确发送出去!");


            }
            else
            {
                handler.BeginSendFile(@"H:/HttpWebServer/index.html", new AsyncCallback(SendFileCallback), new SendFileStateObject(handler));
            }
        }
        static void SendFileCallback(IAsyncResult ar)
        {
            SendFileStateObject st = (SendFileStateObject)ar.AsyncState;
            st.WorkerSocket.EndSendFile(ar);
            st.WorkerSocket.Shutdown(SocketShutdown.Both);
            st.WorkerSocket.Close();
        }
        class ReceiveStateObject
        {
            private Byte[] _buffer;
            private int _size;
            private Socket _s;
            private StringBuilder sb;
            public ReceiveStateObject(Socket woker, int bufferSize)
            {
                _s = woker;
                _size = bufferSize;
                _buffer = new byte[bufferSize];
                sb = new StringBuilder();

            }
            public Socket WorkerSocket
            {
                get { return _s; }
            }

            public int BufferSize
            {
                get { return _size; }
            }
            public Byte[] Buffer
            {
                get { return _buffer; }
            }
            public StringBuilder ContentContainer
            {
                get { return sb; }
            }
        }
        class ResponseStateObject
        {
            public int Len;
            public Socket WorkerSocket;
            public ResponseStateObject(Socket s, int sendLen)
            {
                WorkerSocket = s;
                Len = sendLen;
            }
        }
        class SendStateObject
        {
            private Byte[] _buffer;

            private Socket _s;
            public SendStateObject(Socket socket, byte[] buffer)
            {
                _s = socket;
                _buffer = buffer;

            }
            public Socket WorkerSocket
            {
                get { return _s; }
            }


            public Byte[] Buffer
            {
                get { return _buffer; }
            }
        }

        class SendFileStateObject
        {
            public Socket WorkerSocket;

            public SendFileStateObject(Socket s)
            {
                WorkerSocket = s;
            }
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值