利用HttpListener 模拟web服务器接收本地请求
利用C#中的HttpListener可以模拟web服务器接收web请求。
HttpListener说明:
提供一个简单的、可通过编程方式控制的 HTTP 协议侦听器
名称 | 说明 | |
---|---|---|
AuthenticationSchemes | 获取或设置用于客户端身份验证的方案。 | |
AuthenticationSchemeSelectorDelegate | 获取或设置一个委托,调用它来确定用于客户端身份验证的协议。 | |
DefaultServiceNames | 获取由已注册前缀确定的服务提供程序名 (SPN) 的默认列表。 | |
ExtendedProtectionPolicy | 获取或设置用于会话的扩展保护的 ExtendedProtectionPolicy。 | |
ExtendedProtectionSelectorDelegate | 获取或设置在确定要用于每个请求的 ExtendedProtectionPolicy 时调用的委托。 | |
IgnoreWriteExceptions | 获取或设置 Boolean 值,该值指定应用程序是否接收 HttpListener 向客户端发送响应时发生的异常。 | |
IsListening | 获取一个值,指示 HttpListener 是否已启动。 | |
IsSupported | 获取一个值,指示 HttpListener 是否可用于当前操作系统。 | |
Prefixes | 获取由此 HttpListener 对象处理的统一资源标识符 (URI) 前缀。 | |
Realm | 获取或设置与此 HttpListener 对象关联的领域或资源分区。 | |
TimeoutManager | 此 HttpListener 实例的超时管理器。 | |
UnsafeConnectionNtlmAuthentication | 获取或设置 Boolean 值,该值控制当使用 NTLM 时是否需要对使用同一传输控制协议 (TCP) 连接的其他请求进行身份验证。 |
名称 | 说明 | |
---|---|---|
Abort() | 立刻关闭 HttpListener 对象,这样会放弃所有当前排队的请求。 | |
BeginGetContext(AsyncCallback, Object) | 开始异步检索传入的请求。 | |
Close() | 关闭 HttpListener。 | |
EndGetContext(IAsyncResult) | 完成检索传入的客户端请求的异步操作。 | |
Equals(Object) | 确定指定的对象是否等于当前对象。(继承自 Object。) | |
GetContext() | 等待传入的请求,接收到请求时返回。 | |
GetContextAsync() | 等待传入请求以作为异步操作。 | |
GetHashCode() | 作为默认哈希函数。(继承自 Object。) | |
GetType() | ||
Start() | 允许此实例接收传入的请求。 | |
Stop() | 使此实例停止接收传入的请求。 | |
ToString() | 返回表示当前对象的字符串。(继承自 Object。) |
主要分为以下几步
1.创建一个HTTP侦听器对象并初始化
2.添加需要监听的URI 前缀
3.开始侦听来自客户端的请求
4.处理客户端的Http请求
5.关闭HTTP侦听器
主要核心代码:
public delegate void WndProcDelegater(ref Message m); public class HttpServerBLL { public WndProcDelegater ServerWndProc; public IVShow ivshow; #region public string Host { get; set; } public string port { get; set; } private string _webHomeDir = Application.StartupPath + "\\Web"; private HttpListener listener; private Thread listenThread; private string directorySeparatorChar = Path.DirectorySeparatorChar.ToString(); public string ImageUploadPath { get; set; } /// <summary> /// http服务根目录 /// </summary> public string WebHomeDir { get { return this._webHomeDir; } set { if (!Directory.Exists(value)) throw new Exception("http服务器设置的根目录不存在!"); this._webHomeDir = value; } } /// <summary> /// 服务器是否在运行 /// </summary> public bool IsRunning { get { return (listener == null) ? false : listener.IsListening; } } #endregion #region public HttpServerBLL(string host, string port, string webHomeDir, string imageUploadPath) { this.Host = host; this.port = port; this._webHomeDir = webHomeDir; ImageUploadPath = imageUploadPath; listener = new HttpListener(); } public bool AddPrefixes(string uriPrefix) { string uri = "http://" + uriPrefix + ":" + this.port + "/"; if (listener.Prefixes.Contains(uri)) return false; listener.Prefixes.Add(uri); return true; } /// <summary> /// 启动服务 /// </summary> public void Start() { try { if (listener.IsListening) return; listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; //// 匿名访问 if (!string.IsNullOrEmpty(Host) && Host.Length > 0) { var str = "http://" + Host + ":" + this.port + "/"; listener.Prefixes.Add(str); } else if (listener.Prefixes == null || listener.Prefixes.Count == 0) { var str = "http://localhost:" + this.port + "/"; listener.Prefixes.Add(str); } listener.Start(); //AcceptClient(); listenThread = new Thread(AcceptClient); listenThread.IsBackground = true; listenThread.Name = "httpserver"; listenThread.Start(); } catch (Exception ex) { MessageBox.Show("启动失败"); } } /// <summary> /// 停止服务 /// </summary> public void Stop() { try { if (listener != null) { listener.Stop(); } } catch (Exception ex) { LogHelper.WriteLog(typeof(HttpServerBLL), ex); } } /// <summary> /// /接受客户端请求 /// </summary> void AcceptClient() { while (listener.IsListening) { try { HttpListenerContext context = listener.GetContext(); //new Thread(HandleRequest).Start(context); ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); } catch (Exception ex) { LogHelper.WriteLog(typeof(HttpServerBLL), ex); } } } #endregion #region HandleRequest //处理客户端请求 private void HandleRequest(object ctx) { HttpListenerContext context = ctx as HttpListenerContext; HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; response.Headers["Access-Control-Allow-Origin"] = "*";//避免跨域 try { string rawUrl = System.Web.HttpUtility.UrlDecode(request.RawUrl); int paramStartIndex = rawUrl.IndexOf('?'); if (paramStartIndex > 0) rawUrl = rawUrl.Substring(0, paramStartIndex); else if (paramStartIndex == 0) rawUrl = ""; if (string.Compare(rawUrl, "/ImageUpload", true) == 0) { ImageUploadExec(context); } else if (string.Compare(rawUrl, "/Message", true) == 0) { MessageExec(context); } else if (string.Compare(rawUrl, "/FileImage", true) == 0) { FileImageExec(context); } else { OtherExec(context, rawUrl); } } catch (Exception ex) { LogHelper.WriteLog(typeof(HttpServerBLL), ex); response.StatusCode = 200; response.ContentType = "text/plain"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("接收完成!"); } } try { response.Close(); } catch (Exception ex) { LogHelper.WriteLog(typeof(HttpServerBLL), ex); } } private void OtherExec(HttpListenerContext context, string rawUrl) { HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; #region 网页请求 string InputStream = ""; using (var streamReader = new StreamReader(request.InputStream)) { InputStream = streamReader.ReadToEnd(); } string filePath = ""; if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/") filePath = WebHomeDir + directorySeparatorChar + "Index.html"; else filePath = WebHomeDir + rawUrl.Replace("/", directorySeparatorChar); if (!File.Exists(filePath)) { response.ContentLength64 = 0; response.StatusCode = 404; response.Abort(); } else { response.StatusCode = 200; string exeName = Path.GetExtension(filePath); response.ContentType = GetContentType(exeName); FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Close(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Close(); } #endregion } private void FileImageExec(HttpListenerContext context) { HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; var path = request.QueryString["Path"]; var dirPath = string.Format("{0}\\Image", Application.StartupPath); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } #region 网页请求 string filePath = string.Format("{0}\\{1}", Application.StartupPath, path); if (!File.Exists(filePath)) { response.ContentLength64 = 0; response.StatusCode = 404; response.Abort(); } else { response.StatusCode = 200; string exeName = Path.GetExtension(filePath); response.ContentType = GetContentType(exeName); FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Close(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Close(); } #endregion } private void MessageExec(HttpListenerContext context) { HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; if (ServerWndProc != null) { var w = request.QueryString["width"].ToInt(); var h = request.QueryString["height"].ToInt(); var t = request.QueryString["top"].ToInt(); var l = request.QueryString["left"].ToInt(); if (ivshow != null) { ivshow.ShowVideo(new Size(w, h), new System.Drawing.Point(t, l)); } response.StatusCode = 200; response.OutputStream.Close(); //var m=new Message{ //}; //ServerWndProc(ref m); } } private void ImageUploadExec(HttpListenerContext context) { HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; #region 上传图片 string fileName = context.Request.QueryString["name"]; string filePath = ImageUploadPath + "\\" + DateTime.Now.ToString("yyMMdd_HHmmss_ffff") + Path.GetExtension(fileName).ToLower(); using (var stream = request.InputStream) { using (var br = new BinaryReader(stream)) { IOHelper.WriteStreamToFile(br, filePath, request.ContentLength64); } } response.ContentType = "text/html;charset=utf-8"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("接收完成!"); } #endregion } #endregion #region GetContentType /// <summary> /// 获取文件对应MIME类型 /// </summary> /// <param name="fileExtention">文件扩展名,如.jpg</param> /// <returns></returns> protected string GetContentType(string fileExtention) { if (string.Compare(fileExtention, ".html", true) == 0 || string.Compare(fileExtention, ".htm", true) == 0) return "text/html;charset=utf-8"; else if (string.Compare(fileExtention, ".js", true) == 0) return "application/javascript"; else if (string.Compare(fileExtention, ".css", true) == 0) return "application/javascript"; else if (string.Compare(fileExtention, ".png", true) == 0) return "image/png"; else if (string.Compare(fileExtention, ".jpg", true) == 0 || string.Compare(fileExtention, ".jpeg", true) == 0) return "image/jpeg"; else if (string.Compare(fileExtention, ".gif", true) == 0) return "image/gif"; else if (string.Compare(fileExtention, ".swf", true) == 0) return "application/x-shockwave-flash"; else return "";//application/octet-stream } #endregion }