许明会的计算机技术主页

Language:C,C++,.NET Framework(C#)
Thinking:Design Pattern,Algorithm,WPF,Windows Internals
Database:SQLServer,Oracle,MySQL,PostSQL
IT:MCITP,Exchange,Lync,Virtualization,CCNP

导航

三种方法构建简单的WEB服务器!

《Essential ASP.NET 本质论》举例了Socket编程的基本知识,我稍加修改弄了个简单的应用。
你可以将生成的EXE文件拷贝到服务器上,这样通过任意的WEB浏览器都可以获得该服务器的时间。
这是一个仅仅显示服务器时间的WEB服务器,通过Socket、TcpListener、HttpListener三种方式实现,稍加修改可以作为其他应用。

基本代码如下:三种方法实现的简单WEB服务器下载源代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;

/// <summary>
/// 程序目标:设计一个WEB服务器,向客户端输出服务器的当前时间。
/// 设计思想:
///     构造socketServer对象监听本机的某端口,此处为7788。
///     收到客户端连接请求,打印请求信息。
///     获得本机时间,以HTTP协议格式回应客户端请求。
/// 调试:
///     用netstat -ano 查看端口使用情况
/// </summary>
namespace myIIS
{
    
class Program
    {

        
static void Main(string[] args)
        {
            
//IIS_Socket();
            
//IIS_TcpListener();
            IIS_HttpListener();
        }

        
private static void IIS_HttpListener()
        {
            
if (!HttpListener.IsSupported)
            {
                
throw new System.InvalidOperationException("HttpListener必须为Windows XP SP2 或 Server2003 以上系统运行!");
            }

            
string endpoint = "http://127.0.0.1:7788/";
            HttpListener httpLlisener 
= new HttpListener();
            httpLlisener.Prefixes.Add(endpoint);
            httpLlisener.Start();
            Console.Write(
"WEB服务器正在监听 {0}",endpoint);

            
while (true)
            {
                
//GetContext导致线程阻塞,直到请求到达
                HttpListenerContext context = httpLlisener.GetContext();
                
//HttpListenerRequest request = context.Request;

                
//HttpListenerResponse对象的Content属性设置
                HttpListenerResponse response = context.Response;
                
string body = string.Format(
                    
"<html><head><title>From Socket Server</title></head>" +
                    
"<body><h2>Server Time:{0}</h2></body></html>",
                    System.DateTime.Now);
                response.ContentLength64 
= System.Text.Encoding.UTF8.GetByteCount(body);
                response.ContentType 
= "text/html; charset=UTF-8";

                System.IO.Stream outputStream 
= response.OutputStream;
                System.IO.StreamWriter writer 
= new System.IO.StreamWriter(outputStream);
                writer.Write(body);
                writer.Close();

                
if (Console.KeyAvailable)
                    
break;
            }
            httpLlisener.Stop();
        }

        
/// <summary>
        
/// TcpLisener、TcpClient、NetworkStream
        
/// </summary>
        private static void IIS_TcpListener()
        {
            IPAddress address 
= IPAddress.Loopback;
            IPEndPoint endpoint 
= new IPEndPoint(address, 7788);

            System.Net.Sockets.TcpListener tcpListener 
= new System.Net.Sockets.TcpListener(endpoint);
            tcpListener.Start();
            Console.WriteLine(
"WEB服务器监听中{0}\t……",endpoint);

            
while (true)
            {
                System.Net.Sockets.TcpClient tcpClient 
= tcpListener.AcceptTcpClient();
                System.Net.Sockets.NetworkStream ns 
= tcpClient.GetStream();

                
byte[] buffer = new byte[4096];
                System.Text.Encoding utf8 
= System.Text.Encoding.UTF8;
                
int length = ns.Read(buffer, 0, buffer.Length);
                
string request = utf8.GetString(buffer, 0, length);
                Console.WriteLine(
"WEB客户端请求信息:\n{0}", request);

                
byte[] responseStatusBytes = utf8.GetBytes("HTTP/1.1 200 OK\r\n");
                
byte[] responseBodyBytes = utf8.GetBytes(string.Format(
                    
"<html><head><title>From Socket Server {0}</title></head>" +
                    
"<body><h2>Server Time:{1}</h2></body></html>",
                    endpoint.Address, System.DateTime.Now));
                
byte[] responseHeaderBytes = utf8.GetBytes(string.Format("Content-Type: text/html;" +
                
"charset=UTF-8\r\nContent-length:{0}\r\n", responseBodyBytes.Length));//responseBody.Length

                ns.Write(responseStatusBytes, 
0, responseStatusBytes.Length);
                ns.Write(responseHeaderBytes, 
0, responseHeaderBytes.Length);
                ns.Write(
new byte[] { 1310 }, 02);
                ns.Write(responseBodyBytes, 
0, responseBodyBytes.Length);

                tcpClient.Close();

                
if (Console.KeyAvailable)
                    
break;
            }
            tcpListener.Stop();
        }

        
/// <summary>
        
/// Socket对象
        
/// </summary>
        private static void IIS_Socket()
        {
            
//构建IPAddress、IPEndPoint和Socket对象
            System.Net.IPAddress address = System.Net.IPAddress.Any;    //可以Loopback或其他
            System.Net.IPEndPoint endPoint = new System.Net.IPEndPoint(address, 7788);
            System.Net.Sockets.Socket socketServer 
= new System.Net.Sockets.Socket(
                System.Net.Sockets.AddressFamily.InterNetwork,
                System.Net.Sockets.SocketType.Stream,
                System.Net.Sockets.ProtocolType.Tcp);
            socketServer.Bind(endPoint);  
//将Socket绑定到端口上
            socketServer.Listen(10);          //设置挂起链接队列的长度
            Console.Write("WEB服务器正在监听 {0}", endPoint.Port);

            
while (true)
            {
                
//Accept方法会阻塞线程执行,直到接到客户的连接请求,并返回请求连接的Socket对象
                System.Net.Sockets.Socket socketClient = socketServer.Accept();
                Console.Clear();
                Console.WriteLine(
"\nWEB客户连接请求,来自 {0}", socketClient.RemoteEndPoint);

                
//开始读取客户的请求数据,转换为UTF8编码,并输出请求信息
                byte[] buffer = new byte[4096];
                
int length = socketClient.Receive(buffer, buffer.Length, System.Net.Sockets.SocketFlags.None);
                System.Text.Encoding utf8 
= System.Text.Encoding.UTF8;
                
string request = utf8.GetString(buffer, 0, length);
                Console.WriteLine(
"\n客户端请求信息\n{0}", request);
                
/*
                [Client Established from 127.0.0.1:3438]
                [Received Request Information From WEB Client]:
                GET / HTTP/1.1
                Host: 127.0.0.1:7788
                User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4
                .0
                Accept: text/html,application/xhtml+xml,application/xml;q=0.9,* /*;q=0.8
                Accept-Language: zh-cn,zh;q=0.5
                Accept-Encoding: gzip, deflate
                Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
                Keep-Alive: 115
                Connection: keep-alive
                Cache-Control: max-age=0                 
                 
*/

                
//--应答请求,为便于WEB客户端连接,构造HTTP协议体:状态行、回应体、回应头
                string responseStatus = "HTTP/1.1 200 OK\r\n";
                
byte[] responseStatusBytes = utf8.GetBytes(responseStatus);

                
string responseBody = string.Format(
                    
"<html><head><title>From Socket Server {0}</title></head>" +
                    
"<body><h2>Server Time:{1}</h2></body></html>",
                    endPoint.Address, System.DateTime.Now);
                
byte[] responseBodyBytes = utf8.GetBytes(responseBody);

                
string responseHeader = string.Format("Content-Type: text/html;" +
                
"charset=UTF-8\r\nContent-length:{0}\r\n", responseBody.Length);
                
byte[] responseHeaderBytes = utf8.GetBytes(responseHeader);

                
//--向WEB客户的发送信息:回应状态行、回应头、空行、回应体
                socketClient.Send(responseStatusBytes);
                socketClient.Send(responseHeaderBytes);
                socketClient.Send(
new byte[] { 1310 });
                socketClient.Send(responseBodyBytes);

                socketClient.Close();
                
if (Console.KeyAvailable)
                    
break;
            }
            socketServer.Close();
        }
    }
}

 

posted on 2011-04-09 17:45  许明会  阅读(887)  评论(0编辑  收藏  举报