<![CDATA[
概述
最近因为项目需要,必须自己实现一个HTTP服务器的部分功能。
需求大概是这样的,winform里使用webrowser控件显示一个本地的html页面,同时winform启动http服务,本地html页面里通过javascript使用XMLHttpRequest对象向winform进行http通信,交互数据。
现在,该项目功能基本实现了,把HTTP服务器部分提取出来分享一下,并提供相关源码下载。
HTTP服务器开发教程
启动HTTP服务器代码,创建Socket侦听端口
public void Start(string ip = "127.0.0.1", int port = 80)
{
_IP = ip;
_Port = port;
Stop();
_Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipaddress = IPAddress.Parse(_IP);
IPEndPoint endpoint = new IPEndPoint(ipaddress, _Port);
_Listener.Bind(endpoint);
_Listener.Listen(int.MaxValue);
_Thread = new Thread(new ThreadStart(ThreadHandler));
_Thread.Start();
}
开启一个线程,接收请求的Socket,并且用HttpRequest对象封装处理请求的Socket
private void ThreadHandler()
{
while (true)
{
Socket s = _Listener.Accept();
HttpRequest request = new HttpRequest(this, s);
request.Start();
}
}
每个HttpRequest开启一个新线程处理Socket的发送和接收
public void Start()
{
_Thread = new Thread(new ThreadStart(ThreadHandler));
_Thread.Start();
}
private void ThreadHandler()
{
if (_Server.TraceInConsole)
Console.WriteLine("Begin HttpRequest...");
try
{
while (true)
{
string receive = Receive();
if (!string.IsNullOrEmpty(receive))
{
_Server.ReadRequest(this, receive);
string response = _Server.GetResponse(this);
int write = Send(response);
_Server.ResponseFinished(this);
while (true)
{
Thread.Sleep(3000);
write = Send(HttpServer.BYTES_CRLF);
if (_Client == null)
break;
}
}
if (_Client == null)
break;
Thread.Sleep(1000);
}
}
catch (Exception ex)
{
if (_Server.TraceInConsole)
Console.WriteLine(ex.Message);
}
if (_Server.TraceInConsole)
Console.WriteLine("End HttpRequest...");
}
处理HTTP请求,默认是返回http404错误,在GetResponse添加自定义http处理
public virtual string GetResponse(HttpRequest request)
{
return ResponeNotFound(request.Version);
}
public string ResponeNotFound(string version)
{
return version + @" 404 Not Found
Content-Length: 0
Content-Type: text/plain
Server: Hunk's http server
Date: Fri, 06 Aug 2010 14:00:23 GMT
";
}
处理Socket关闭,TIME_WAIT状态
如果服务端的Socket比客户端的Socket先关闭,会导致客户端出现TIME_WAIT状态,占用系统资源。
服务端尝试发送数据,利用SocketExeception判断客户端Socket是否已关闭连接,然后关闭服务端Socket。
…
while (true)
{
Thread.Sleep(3000);
write = Send(HttpServer.BYTES_CRLF); //如果发送失败,_Client会被关闭并且设置为null
if (_Server.TraceInConsole)
Console.WriteLine("Try To End HttpRequest...");
if (_Client == null)
break;
}
…
注:只提点主要的位置,详细请下载源码。
HTTP服务器和客户端的效果图
源码下载地址
http://download.youkuaiyun.com/source/2602863
]]>