说明:服务器和浏览器之间通信大致通过:连接->请求->处理->响应等过程
1 创建服务器(form应用程序)
1.1 首先需要两个对象 Request 和 Response
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Service { //请求报文 public class HttpRequest { //请求方式-属性 public string Method { get; set; } //请求地址-属性 public string Url { get; set; } //请求版本-属性 public string Protocol { get; set; } //构造方法 public HttpRequest(string strRequest) { //此时head Get http://baidu.com... HTTP/1.1 string head = strRequest.Replace(" ", "$").Split('$')[0]; String [] headList = head.Split(' '); Method = headList[0]; //将请求文件转成绝对路径 Url = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), headList[1].Substring(1)); Protocol = headList[2]; } } }
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Service { public class HttpResponse { public HttpResponse(HttpRequest request) { //url /a/b.html //获取文件扩展名--确定类型 type = GetType(Path.GetExtension(request.Url)); //获取文件大小 } public int Length { set; get; } private string type; #region 04-属性-响应报文头 public byte[] Head { get { byte[] bs; StringBuilder sb = new StringBuilder(); sb.AppendLine("HTTP/1.1 200 OK"); sb.AppendLine("Dage: " + DateTime.Now); sb.AppendLine("Server: XYXTL"); sb.AppendLine("Content-Length: " + Length); sb.AppendLine("Content-Type: " + type); sb.AppendLine(); bs = Encoding.UTF8.GetBytes(sb.ToString()); return bs; } } #endregion #region 05-方法 获取响应报文的类型 private string GetType(string ext) { string type = "text/html;charset=urf-8"; switch (ext) { case ".aspx": case ".html": case ".htm": type = "text/html;charset=urf-8"; break; case ".png": type = "image/png"; break; case ".gif": case ".GIF": type = "image/gif"; break; case ".jpg": case ".jpeg": type = "image/jpeg"; break; case ".css": type = "text/css"; break; case ".js": type = "application/x-javascript"; break; default: type = "text/plain;charset=gbk"; break; } return type; } #endregion #region 05-属性-响应报文体 public byte[] Body { get ; set ; } #endregion } }
1.2 将对象进一步封装 Context
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Service { public class HttpContext { public HttpRequest Request { set; get; } public HttpResponse Response { set; get; } public HttpContext(string str) { Request = new HttpRequest(str); Response = new HttpResponse(Request); } } }
1.3 如果是静态方法直接获取,如果是动态的需要进一步定位到响应的cs文件中
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Sockets; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Service { public class HttpApplication { public void ProcessRequest(HttpContext context, Socket clientSok) { //根据文件的扩展名,判断是否为动态文件 string ext = Path.GetExtension(context.Request.Url); if (ext == ".aspx") { //动态文件 //01 获取请求的名称--C:ac.aspx === c string className = Regex.Match(context.Request.Url,@".+\(.+).aspx").Groups[1].Value; //02 根据名字 反射类 IHttpHandeler handel = Assembly.GetExecutingAssembly().CreateInstance("Service." + className) as IHttpHandeler; handel.ProcessRequest(context); } else { //静态文件--直接把字节数组交给file读取 byte [] bs = File.ReadAllBytes(context.Request.Url); context.Response.Length = bs.Length; context.Response.Body = bs; } clientSok.Send(context.Response.Head); clientSok.Send(context.Response.Body); } } }
1.4 动态--通过接口和反射实现
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Service { public interface IHttpHandeler { void ProcessRequest(HttpContext context); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Service { public class yk:IHttpHandeler { public void ProcessRequest(HttpContext context) { string str = "<b>逍遥小天狼</b>"; byte [] bs = Encoding.UTF8.GetBytes(str); context.Response.Body = bs; context.Response.Length = bs.Length; } } }
1.5 实现效果