关于HTTP协议的具体内容,前面章节已经有所讲解,相信读者已有所了解,在此不在累述,本章节讲解自定义web服务器。

 一,.net提供自定义Web服务器的类

以下只是写主要的类

1.HTTPListener:对TCPListener的封装

2.TCPListener:对Socket的封装

3.Socket:对协议栈传输层接口的封装

 二,用.net提供的类进行web服务器的自定义

1.用HTTPListener

  1. using System;
  2. using System.Net;
  3. using System.IO;
  4. using System.Text;
  5. using System.Globalization;
  6. using System.Threading;
  7.  
  8. namespace Microsoft.Samples.HttpListener
  9. {
  10. static class HttpRequestListener
  11. {
  12. public static void Main()
  13. {
  14. string[] prefixes = new string[];
  15. prefixes[] = "http://localhost:8080/";
  16. ProcessRequests(prefixes);
  17. }
  18.  
  19. private static void ProcessRequests(string[] prefixes)
  20. {
  21. if (!System.Net.HttpListener.IsSupported)
  22. {
  23. Console.WriteLine(
  24. "Windows XP SP2, Server 2003, or higher is required to " +
  25. "use the HttpListener class.");
  26. return;
  27. }
  28. // URI prefixes are required,
  29. if (prefixes == null || prefixes.Length == )
  30. throw new ArgumentException("prefixes");
  31.  
  32. // Create a listener and add the prefixes.
  33. System.Net.HttpListener listener = new System.Net.HttpListener();
  34. Thread handleRequest = null;
  35. foreach (string s in prefixes)
  36. {
  37. listener.Prefixes.Add(s);
  38. }
  39.  
  40. try
  41. {
  42. // 启动监听,开始监听请求
  43. listener.Start();
  44. Console.WriteLine("Listening...");
  45.  
  46. while(true)
  47. {
  48. HttpListenerResponse response = null;
  49.  
  50. // GetContext 在等待一个请求时将阻塞 .
  51. HttpListenerContext context = listener.GetContext();
  52.  
  53. handleRequest = new Thread(delegate()
  54. {
  55. try
  56. {
  57. Console.WriteLine("当前线程是否为线程池线程:" + (Thread.CurrentThread.IsThreadPoolThread==true?"是":"否"));
  58. Console.WriteLine("当前线程总数:" + System.Diagnostics.Process.GetCurrentProcess().Threads.Count.ToString());
  59. response = context.Response;
  60.  
  61. string responseBody =
  62. "<HTML><head><script language='javascript' type='text/javascript'>function test(){alert('你好');}</script></head><BODY><form>The time is currently " + DateTime.Now.ToString() + "<br/>";
  63. responseBody += "<input type='button' value='js测试' id='test1' onclick='test();'/><br/><input type='submit' value='提交测试' id='test2' /></form></BODY></HTML>";
  64. string responseHeader =
  65. string.Format(
  66. "Content-Type: text/html; charset=UTf-8;Content-Length: {0}", responseBody.Length);
  67.  
  68. byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);
  69. response.ContentLength64 = responseBodyBytes.Length;
  70. System.IO.Stream output = response.OutputStream;
  71. // 向客户端发送回应头信息
  72. response.Headers.Add(responseHeader);
  73. // 向客户端发送状态行
  74. response.StatusCode = (int)HttpStatusCode.OK;
  75. response.ProtocolVersion = Version.Parse("1.1");
  76. // 想客户端发送主体部分
  77. output.Write(responseBodyBytes, , responseBodyBytes.Length);
  78. }
  79. catch (HttpListenerException ex)
  80. {
  81. Console.WriteLine(ex.Message);
  82. }
  83. finally
  84. {
  85. if (response != null)
  86. response.Close();
  87. }
  88. Thread.Sleep();
  89. });
  90. handleRequest.Start();
  91. }
  92. }
  93. catch (HttpListenerException ex)
  94. {
  95. Console.WriteLine(ex.Message);
  96. }
  97. finally
  98. {
  99. //停止监听
  100. listener.Close();
  101. Console.WriteLine("Done Listening.");
  102. }
  103. }
  104. }
  105. }

服务端运行效果:

客户端运行效果:

2.用TCPListener

  1. private static void ProcessRequestsWithTcpListener()
  2. {
  3. TcpListener server=new TcpListener(IPAddress.Any,);
  4.  
  5. server.Start();
  6.  
  7. Console.WriteLine("HTTP Server Start Listening....");
  8.  
  9. while (true)
  10. {
  11. TcpClient client = server.AcceptTcpClient();
  12. Thread handleRequest = new Thread(delegate()
  13. {
  14. try
  15. {
  16. NetworkStream inputoutputstream = client.GetStream();
  17. Byte[] buffer = new Byte[];
  18. int readLength = inputoutputstream.Read(buffer, , buffer.Length);
  19. String inputoutputstring = Encoding.ASCII.GetString(buffer, , readLength);
  20.  
  21. Console.WriteLine("客户端信息:" + client.Client.RemoteEndPoint);
  22. Console.WriteLine("客户端请求信息:\n" + inputoutputstring);
  23.  
  24. String statusLine = "HTTP/1.1 200 OK\r\n";
  25. string responseBody =
  26. "<HTML><head><script language='javascript' type='text/javascript'>function test(){alert('你好');}</script></head><BODY><form>The time is currently " + DateTime.Now.ToString() + "<br/>";
  27. responseBody += "<input type='button' value='js测试' id='test1' onclick='test();'/><br/><input type='submit' value='提交测试' id='test2' /></form></BODY></HTML>";
  28. string responseHeader =
  29. string.Format(
  30. "Content-Type: text/html; charset=UTf-8\r\nContent-Length: {0}\r\n", responseBody.Length + statusLine.Length);
  31. byte[] responseStatusLineBytes = Encoding.UTF8.GetBytes(statusLine);
  32. byte[] responseHeaderBytes = Encoding.UTF8.GetBytes(responseHeader);
  33. byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);
  34.  
  35. // 写入状态行信息
  36. inputoutputstream.Write(responseStatusLineBytes, , responseStatusLineBytes.Length);
  37. // 写入回应的头部
  38. inputoutputstream.Write(responseHeaderBytes, , responseHeaderBytes.Length);
  39. // 写入回应头部和内容之间的空行
  40. inputoutputstream.Write(new byte[] { , }, , );
  41.  
  42. // 写入回应的内容
  43. inputoutputstream.Write(responseBodyBytes, , responseBodyBytes.Length);
  44. }
  45. catch (Exception ex)
  46. {
  47. Console.WriteLine("异常信息:"+ex.Message);
  48. }
  49. finally
  50. {
  51. // 关闭与客户端的连接
  52. client.Close();
  53. }
  54.  
  55. });
  56. handleRequest.Start();
  57. }
  58. }

服务端运行效果:

客户端运行效果:和1类似

3.用Socket

  1. private static void ProcessRequestsWithSocket()
  2. {
  3. Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  4. server.Bind(new IPEndPoint(IPAddress.Any, ));
  5. server.Listen();
  6.  
  7. Console.WriteLine("HTTP Server Start Listening....");
  8.  
  9. while (true)
  10. {
  11. Socket client = server.Accept();
  12. Thread handleRequest = new Thread(delegate()
  13. {
  14. try
  15. {
  16. Byte[] buffer = new Byte[];
  17. int readLength = client.Receive(buffer, buffer.Length,SocketFlags.None);
  18. String inputoutputstring = Encoding.ASCII.GetString(buffer, , readLength);
  19.  
  20. Console.WriteLine("客户端信息:" + client.RemoteEndPoint);
  21. Console.WriteLine("客户端请求信息:\n" + inputoutputstring);
  22.  
  23. String statusLine = "HTTP/1.1 200 OK\r\n";
  24. string responseBody =
  25. "<HTML><head><script language='javascript' type='text/javascript'>function test(){alert('你好');}</script></head><BODY><form>The time is currently " + DateTime.Now.ToString() + "<br/>";
  26. responseBody += "<input type='button' value='js测试' id='test1' onclick='test();'/><br/><input type='submit' value='提交测试' id='test2' /></form></BODY></HTML>";
  27. string responseHeader =
  28. string.Format(
  29. "Content-Type: text/html; charset=UTf-8\r\nContent-Length: {0}\r\n", responseBody.Length + statusLine.Length);
  30. byte[] responseStatusLineBytes = Encoding.UTF8.GetBytes(statusLine);
  31. byte[] responseHeaderBytes = Encoding.UTF8.GetBytes(responseHeader);
  32. byte[] responseBodyBytes = Encoding.UTF8.GetBytes(responseBody);
  33.  
  34. // 写入状态行信息
  35. client.Send(responseStatusLineBytes);
  36. // 写入回应的头部
  37. client.Send(responseHeaderBytes);
  38. // 写入回应头部和内容之间的空行
  39. client.Send(new byte[] { , });
  40.  
  41. // 写入回应的内容
  42. client.Send(responseBodyBytes);
  43. }
  44. catch (Exception ex)
  45. {
  46. Console.WriteLine("异常信息:" + ex.Message);
  47. }
  48. finally
  49. {
  50. // 关闭与客户端的连接
  51. client.Close();
  52. }
  53.  
  54. });
  55. handleRequest.Start();
  56. }
  57. }

服务端和客户端运行效果和2类似.
    声明:2和3代码修改自:http://www.cnblogs.com/zhili/archive/2012/08/23/WebServer.html 只为交流,不为商用.

备注:面试时,常问的一个问题是:http中post和get请求的区别

个人感觉:1.两者传输方式不同,post将数据放在请求内容里传输,get放在请求行传输

2.post内容没有大小限制,get内容有大小限制。

自定义web服务器(四)的更多相关文章

  1. atitit.跨架构 bs cs解决方案. 自定义web服务器的实现方案 java .net jetty  HttpListener

    atitit.跨架构 bs cs解决方案. 自定义web服务器的实现方案 java .net jetty  HttpListener 1. 自定义web服务器的实现方案,基于原始socket vs   ...

  2. 网络知识 - 简易的自定义Web服务器

    简易的自定义Web服务器 基于浏览器向服务端发起请求 两台主机各自的进程之间相互通信,需要协议.IP地址和端口号,IP表示了主机的网络地址,而端口号则表示了主机上的某个进程的地址,IP加Port统称为 ...

  3. [C# 网络编程系列]专题三:自定义Web服务器

    转自:http://www.cnblogs.com/zhili/archive/2012/08/23/2652460.html 前言: 经过前面的专题中对网络层协议和HTTP协议的简单介绍相信大家对网 ...

  4. 转:【专题三】自定义Web服务器

    前言: 经过前面的专题中对网络层协议和HTTP协议的简单介绍相信大家对网络中的协议有了大致的了解的, 本专题将针对HTTP协议定义一个Web服务器,我们平常浏览网页通过在浏览器中输入一个网址就可以看到 ...

  5. 专题三:自定义Web服务器

    前言: 经过前面的专题中对网络层协议和HTTP协议的简单介绍相信大家对网络中的协议有了大致的了解的, 本专题将针对HTTP协议定义一个Web服务器,我们平常浏览网页通过在浏览器中输入一个网址就可以看到 ...

  6. ASP.NET 开发必备知识点(1):如何让Asp.net网站运行在自定义的Web服务器上

    一.前言 大家都知道,在之前,我们Asp.net 的网站都只能部署在IIS上,并且IIS也只存在于Windows上,这样Asp.net开发的网站就难以做到跨平台.由于微软的各项技术的开源,所以微软自然 ...

  7. net网站运行在自定义的Web服务器上

    ASP.NET 开发必备知识点(1):如何让Asp.net网站运行在自定义的Web服务器上   一.前言 大家都知道,在之前,我们Asp.net 的网站都只能部署在IIS上,并且IIS也只存在于Win ...

  8. nginx 隐藏版本号与WEB服务器信息

    nginx不仅可以隐藏版本信息,还支持自定义web服务器信息 先看看最终的隐藏结果吧 具体怎么实现呢,其实也很简单,请往下看 1 官网下载最新稳定版 wget http://nginx.org/dow ...

  9. Visual Studio中用于ASP.NET Web项目的Web服务器

    当您在 Visual Studio 中开发 Web 项目时,需要 Web 服务器才能测试或运行它们. 利用 Visual Studio,您可以使用不同的 Web 服务器进行测试,包括 IIS Expr ...

随机推荐

  1. HTML Music Entities/音乐符号

    HTML Music Entities Musical symbols Description Character(click) HTML-Entity Code-Decimal Code-Hex Q ...

  2. What are the differences between small, minor, and major updates?

    Following contents are excerpted from the this website and only used for knowledge sharing:  Install ...

  3. Mac或Linux中对Android抓包

    转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/mac-or-linux-android-caught/ 说明 首先要到http://www.charlesp ...

  4. [DevExpress]SplitContainerControl使用小计

    1.修改成纵向分割 Horizontal = false; 2.设置伸缩箭头 3.固定某个PANEL大小 最大化后依然保持着比例 4.隐藏某个PANEL splitContainerControl1. ...

  5. 1. Window环境下 - 开发环境的配置: (安装Android Studio 2.1)

    0. Java简介: 1990年Sun公司预料嵌入式系统将在未来家用电器领域大显生手, 于是成立了一个由James Gosling领导的"Green计划"(首席科学家Bill Jo ...

  6. PHP 提取图片img标记中的任意属性

    PHP 提取图片img标记中的任意属性的简单实例. 复制代码代码如下: <?php /* PHP正则提取图片img标记中的任意属性 */ $str = '<center><im ...

  7. [CSS]visibility 属性

    定义和用法 visibility 属性规定元素是否可见. 提示:即使不可见的元素也会占据页面上的空间.请使用 "display" 属性来创建不占据页面空间的不可见元素. 说明 这个 ...

  8. 【10】了解Bootstrap栅格系统基础案例(5)

    这次我们来说下列排序: 通过使用 .col-md-push-* 和 .col-md-pull-* 类就可以很容易的改变列(column)的顺序. <!DOCTYPE html> <h ...

  9. Rsync+Inotify-tools实现数据实时同步

    inotify是一种强大的,细粒度的,异步文件系统时间监控机制,它可以替代crond实现与rsync的触发式文件同步,从而监控文件系统中添加,删除,修改,移动等细粒事件,从LINUX 2.6.13起, ...

  10. [Python][flask][flask-wtf]关于flask-wtf中API使用实例教程

    简介:简单的集成flask,WTForms,包括跨站请求伪造(CSRF),文件上传和验证码. 一.安装(Install) 此文仍然是Windows操作系统下的教程,但是和linux操作系统下的运行环境 ...