使用HttpListener实现简单的Http服务

HttpListener提供一个简单的、可通过编程方式控制的 HTTP 协议侦听器.使用它可以很容易的提供一些Http服务,而无需启动IIS这类大型服务程序。使用HttpListener的方法流程很简单:主要分为以下几步
  1. 创建一个HTTP侦听器对象并初始化
  2. 添加需要监听的URI 前缀
  3. 开始侦听来自客户端的请求
  4. 处理客户端的Http请求
  5. 关闭HTTP侦听器

例如:我们要实现一个简单Http服务,进行文件的下载,或者进行一些其他的操作,例如要发送邮件,使用HttpListener监听,处理邮件队列,避免在网站上的同步等待。以及获取一些缓存的数据等等行为

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using System.IO;
using Newtonsoft.Json;

namespace HttpListenerApp
{
    /// <summary>
    /// HttpRequest逻辑处理
    /// </summary>
    public class HttpProvider
    {

        private static HttpListener httpFiledownload;  //文件下载处理请求监听
        private static HttpListener httOtherRequest;   //其他超做请求监听

        /// <summary>
        /// 开启HttpListener监听
        /// </summary>
        public static void Init()
        {
            httpFiledownload = new HttpListener(); //创建监听实例
            httpFiledownload.Prefixes.Add("http://10.0.0.217:20009/FileManageApi/Download/"); //添加监听地址 注意是以/结尾。
            httpFiledownload.Start(); //允许该监听地址接受请求的传入。
            Thread ThreadhttpFiledownload = new Thread(new ThreadStart(GethttpFiledownload)); //创建开启一个线程监听该地址得请求
            ThreadhttpFiledownload.Start();

            httOtherRequest = new HttpListener();
            httOtherRequest.Prefixes.Add("http://10.0.0.217:20009/BehaviorApi/EmailSend/");  //添加监听地址 注意是以/结尾。
            httOtherRequest.Start(); //允许该监听地址接受请求的传入。
            Thread ThreadhttOtherRequest = new Thread(new ThreadStart(GethttOtherRequest));
            ThreadhttOtherRequest.Start();
        }

        /// <summary>
        /// 执行文件下载处理请求监听行为
        /// </summary>
        public static void GethttpFiledownload()
        {
            while (true)
            {
                HttpListenerContext requestContext = httpFiledownload.GetContext(); //接受到新的请求
                try
                {
                    //reecontext 为开启线程传入的 requestContext请求对象
                    Thread subthread = new Thread(new ParameterizedThreadStart((reecontext) =>
                    {
                        Console.WriteLine("执行文件处理请求监听行为");

                        var request = (HttpListenerContext)reecontext;
                        var image =  HttpUtility.UrlDecode(request.Request.QueryString["imgname"]); //接受GET请求过来的参数;
                        string filepath = AppDomain.CurrentDomain.BaseDirectory + image;
                        if (!File.Exists(filepath))
                        {
                            filepath = AppDomain.CurrentDomain.BaseDirectory + "default.jpg";       //下载默认图片
                        }
                        using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
                        {
                            byte[] buffer = new byte[fs.Length];
                            fs.Read(buffer, , (int)fs.Length); //将文件读到缓存区
                            request.Response.StatusCode = ;
                            request.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                            request.Response.ContentType = "image/jpg";
                            request.Response.ContentLength64 = buffer.Length;
                            var output = request.Response.OutputStream; //获取请求流
                            output.Write(buffer, , buffer.Length);     //将缓存区的字节数写入当前请求流返回
                            output.Close();
                        }
                    }));
                    subthread.Start(requestContext); //开启处理线程处理下载文件
                }
                catch (Exception ex)
                {
                    try
                    {
                        requestContext.Response.StatusCode = ;
                        requestContext.Response.ContentType = "application/text";
                        requestContext.Response.ContentEncoding = Encoding.UTF8;
                        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("System Error");
                        //对客户端输出相应信息.
                        requestContext.Response.ContentLength64 = buffer.Length;
                        System.IO.Stream output = requestContext.Response.OutputStream;
                        output.Write(buffer, , buffer.Length);
                        //关闭输出流,释放相应资源
                        output.Close();
                    }
                    catch { }
                }
            }
        }

        /// <summary>
        /// 执行其他超做请求监听行为
        /// </summary>
        public static void GethttOtherRequest()
        {
            while (true)
            {
                HttpListenerContext requestContext = httOtherRequest.GetContext(); //接受到新的请求
                try
                {
                    //reecontext 为开启线程传入的 requestContext请求对象
                    Thread subthread = new Thread(new ParameterizedThreadStart((reecontext) =>
                    {
                        Console.WriteLine("执行其他超做请求监听行为");
                        var request = (HttpListenerContext)reecontext;
                        var msg = HttpUtility.UrlDecode(request.Request.QueryString["behavior"]); //接受GET请求过来的参数;
                        //在此处执行你需要进行的操作>>比如什么缓存数据读取,队列消息处理,邮件消息队列添加等等。

                        request.Response.StatusCode = ;
                        request.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                        request.Response.ContentType = "application/json";
                        requestContext.Response.ContentEncoding = Encoding.UTF8;
                        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { success = true, behavior = msg }));
                        request.Response.ContentLength64 = buffer.Length;
                        var output = request.Response.OutputStream;
                        output.Write(buffer, , buffer.Length);
                        output.Close();
                    }));
                    subthread.Start(requestContext); //开启处理线程处理下载文件
                }
                catch (Exception ex)
                {
                    try
                    {
                        requestContext.Response.StatusCode = ;
                        requestContext.Response.ContentType = "application/text";
                        requestContext.Response.ContentEncoding = Encoding.UTF8;
                        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("System Error");
                        //对客户端输出相应信息.
                        requestContext.Response.ContentLength64 = buffer.Length;
                        System.IO.Stream output = requestContext.Response.OutputStream;
                        output.Write(buffer, , buffer.Length);
                        //关闭输出流,释放相应资源
                        output.Close();
                    }
                    catch { }
                }
            }
        }
    }
}

调用方式:注意这里启动程序必须以管理员身份运行,因为上午的监听需要开启端口,所有需要以管理员身份运行。

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

namespace HttpListenerApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //开启请求监听
            HttpProvider.Init();
        }
    }
}
执行后的结果为:

这里通过一个简单的控制程序在里面使用HttpListener实现了简单的Http服务程序。里面有少量的线程和和异步处理,比如收到行为信息请求可以先返回给用户,让用户不用同步等待,就可以执行下一步操作,又比如实现的简单邮件服务器,将请求发给HttpListener接收到请求后就立即返回,交给队列去发送邮件。邮件的发送会出现延迟等待等情况出现,这样就不用等待。等等

通过HttpListener实现简单的Http服务的更多相关文章

  1. 利用HttpListener创建简单的HTTP服务

    using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using ...

  2. 树莓派(Raspberry Pi)搭建简单的lamp服务

    树莓派(Raspberry Pi)搭建简单的lamp服务: 1. LAMP 的安装 sudo apt-get install apache2 mysql-server mysql-client php ...

  3. 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介

    构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ...

  4. Netty4.0学习笔记系列之三:构建简单的http服务(转)

    http://blog.csdn.net/u013252773/article/details/21254257 本文主要介绍如何通过Netty构建一个简单的http服务. 想要实现的目的是: 1.C ...

  5. 简单ESB的服务架构

    简单ESB的服务架构 这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1. ...

  6. 新项目架构从零开始(三)------基于简单ESB的服务架构

    这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1.Common 在Com ...

  7. 简单 TCP/IP 服务功能

    本主题使用每台 Windows 计算机上提供的 Echo 和 Quote of the Day 服务.在所有 Windows 版本中都提供了简单 TCP/IP 服务功能.该功能会提供了以下服务:Cha ...

  8. 使用Topshelf组件构建简单的Windows服务

    很多时候都在讨论是否需要了解一个组件或者一个语言的底层原理这个问题,其实我个人觉得,对于这个问题,每个人都有自己的看法,个人情况不同,选择的方式也就会不同了.我个人觉得无论学习什么,都应该尝试着去了解 ...

  9. 使用Axis2创建一个简单的WebService服务

    使用过Java进行过WebService开发都会听过或者接触过Apache Axis2,Axis2框架是应用最广泛的WebService框架之一了. 这里使用Axis2来开发和部署一个最简单的WebS ...

随机推荐

  1. C/C++ makefile自动生成工具(comake2,autotools,linux),希望能为开源做点微薄的贡献!

      序     在linux下C或C++项目开发,Makefile是必备的力气,但是发现手写很麻烦. 在百度有个comake2工具,用于自动生成Makefile工具,而在外边本想找一个同类工具,但发现 ...

  2. 小型文件数据库 (a file database for small apps) SharpFileDB

    小型文件数据库 (a file database for small apps) SharpFileDB For english version of this article, please cli ...

  3. Module Zero之角色管理

    返回<Module Zero学习目录> 角色实体 角色管理者 多租户 角色实体 角色实体代表了该应用的一个角色.它应该派生自AbpRole类,如下所示: public class Role ...

  4. Eclipse安装ZooKeeper插件

    Eclipse在线安装插件奇慢的解决办法 安装ZooKeeper插件步骤如下:Step 1. 在 Eclipse 菜单打开Help -> Install New Software…Step 2. ...

  5. 修改windows自带的Ctrl+Space输入法切换快捷键

    使用场景: 多为我等码农使用一些编辑器时,编辑器的默认代码提示热键为 ctrl+space ,但这个热键被系统的输入法开关占用.如果遇到可以设置快捷键的编辑器还好,要是不能设置的话(比如火狐浏览器的代 ...

  6. Kali信息收集系列:(都是我以前的笔记整理了一下,就没加水印,习惯就好)

    好几天没发微信公众号了,今天一起发下.(最近有点事情) 前些天老业界的一位朋友问我一些Safe新时代信息收集的问题 逆天虽然好多年不干老本行,但隔段时间都会关注一下 于是就花了点时间整理了一下,你们就 ...

  7. 【Win 10开发】协议-上篇:自定义应用协议

    就像系统许多内置应用可以通过URI来启动(如ms-settings-bluetooth:可以打开蓝牙设置页),我们自己开发的应用程序,如果需要的话,可以为应用程序自定义一个协议.应用程序协议在安装时会 ...

  8. 让setTimeout支持链式

    修改很简单,通过参数判断,然后返回下promise对象 (function() { var timeout = setTimeout; window.setTimeout = function(fn, ...

  9. 推荐12个漂亮的 CSS3 按钮实现方案

    在过去,我们都是使用图片或者JavaScript来实现漂亮的按钮效果,随着越来越多的浏览器对CSS3的支持和完善,使用CSS3来实现美观的按钮已没有太多的障碍.今天,本文收集了12个很不错的CSS3按 ...

  10. Notes:SVG(1)

    SVG,"Scalable Vector Graphics"可伸缩矢量图形,基于可扩展标记语言,用于描述二维矢量图形的一种图形格式. SVG是纯粹的XML,可以使用以下方法插入到H ...