初体验开发一个HttpServer雏形
2010-11-16 10:21 CleverDeng 阅读(4141) 评论(6) 编辑 收藏 举报记得迷上Python的那段时间,同时也关注了IronPython一段时间,IronPython项目的源代码中就包含了一个简单的HttpServer,因为一直都对Web服务器的运行机制很感兴趣,因此研究了一下源代码并跟踪调试,也让我这服务器开发的门外汉体验了一把。
熟话说,看归看,写归写,写程序远比看懂代码有难度多了,于是乎堆码热情澎湃,堆了一个HttpServer雏形(实现原理的模型)
一、阻塞模型
阻塞模型,当您的程序运行到某条代码时(请求I/O操作),当前进程将等待在调用处,后面的语句将不继续执行,直到引起阻塞的语句执行完毕后,等待出后面的语句将可继续执行,从这里我们可以知道,阻塞模型严重浪费计算机的资源,然而非阻塞将是该方案的替代者。我们先看看阻塞模型的实现代码:
首先,我们开启一个接受来自客户端请求的Socket并与IP地址和端口绑定,然后监听该Socket。
public static void OpenServer() { server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000)); server.Listen(0); }
public static void BlockingSelect() { string response = "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\n"; response += "<html><head><title>服务器</title></head><body><p style='color:red'>Hello World</p></body></html>"; while (true) { Socket temps = server.Accept(); byte[] buffer = new byte[server.SendBufferSize]; temps.Receive(buffer); string request=System.Text.Encoding.Default.GetString(buffer); Console.WriteLine(request); temps.Send(System.Text.Encoding.Default.GetBytes(response)); temps.Close(); } }
二、非阻塞模型
非阻塞模型,在Linux下一个很受大家欢迎的是epoll,一般开源项目(网络开发)使用到epoll的话,基本上都是好东西。而在windows下下提供了5种选择(Select,WSAAsyncSelect,WSAEventSelect,Overlapped I/O,Completion Port),本小段代码就使用异步选择(WSAAsyncSelect),因为它是最简单的,一个主线程就可以搞定,这可都要归功于Windows的(事件)消息机制。代码如下:
public static void OpenServer() { tcpServer = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000)); tcpServer.Start(1000); } public static void NoBlockingSelect() { while (true) { if (tcpServer.Pending())(1) { tcpServer.BeginAcceptSocket(new AsyncCallback(CallBack), tcpServer);(2) } } } public static void CallBack(IAsyncResult obj) { if (obj.IsCompleted) { string response = "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\n"; response += "<html><head><title>服务器</title></head><body><p style='color:red'>Hello World" + DateTime.Now.ToString("hh:mm:ss") + "</p></body></html>"; Socket tempserver = tcpServer.EndAcceptSocket(obj); byte[] buffer = new byte[tempserver.ReceiveBufferSize]; tempserver.Receive(buffer, tempserver.ReceiveBufferSize, SocketFlags.None); string request = System.Text.Encoding.Default.GetString(buffer); Console.WriteLine(request.Trim()); tempserver.Send(System.Text.Encoding.Default.GetBytes(response)); tempserver.Close(); } }
三、总结
通过上面的2种Socket编程模型,玩成了一个HttpServer的雏形,如果想象力丰富一点,我们可以使用上面的非阻塞模型改造成一个Web游戏服务器,我现在就在使用Python+epoll进行试验,您不妨也体验一番。