c# 使用 HttpListener

通过HttpListener实现简单的Http服务

HttpListener提供一个简单的、可通过编程方式控制的 HTTP 协议侦听器。通过它可以很容易的提供一些Http服务,而无需启动IIS这类大型服务程序。

注意:该类仅在运行 Windows XP SP2 或 Windows Server 2003 操作系统的计算机上可用。

使用Http服务一般步骤如下:

  1. 创建一个HTTP侦听器对象并初始化

  2. 添加需要监听的URI 前缀

  3. 开始侦听来自客户端的请求

  4. 处理客户端的Http请求

  5. 关闭HTTP侦听器

其中3,4两步可以循环处理,以提供多客户多次请求的服务。

创建一个HTTP侦听器对象

创建HTTP侦听器对象只需要新建一个HttpListener对象即可。

HttpListener listener = new HttpListener();

初始化需要经过如下两步

  1. 添加需要监听的URL范围至listener.Prefixes中,可以通过如下函数实现:
    listener.Prefixes.Add(prefix)    //prefix必须以'/'结尾
  2. 调用listener.Start()实现端口的绑定,并开始监听客户端的需求。

接受HTTP请求

在.net2.0中,通过HttpListenerContext对象提供对HttpListener类使用的请求和响应对象的访问。

获取HttpListenerContext的最简单方式如下:

HttpListenerContext context = listener.GetContext();

该方法将阻塞调用函数至接收到一个客户端请求为止,如果要提高响应速度,可使用异步方法listener.BeginGetContext()来实现HttpListenerContext对象的获取。

处理HTTP请求

获取HttpListenerContext后,可通过Request属性获取表示客户端请求的对象,通过Response属性取表示 HttpListener 将要发送到客户端的响应的对象。

HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;

这里的HttpListenerRequest对象和HttpListenerResponse对象和Asp中的Request和Response的使用方式类似,这里就不多说了,具体的使用可以参看下面的例子。

关闭HTTP侦听器

通过调用listener.Stop()函数即可关闭侦听器,并释放相关资源

代码示例:

class Program {

        private static Httplistener _socket;

        static void Main(string[] args) {

            _socket = new Httplistener();

            _socket.HttpEvent += HttpMsgEvent;
            _socket.Start("http://+:8080/POST/");

            Console.ReadKey();
        }

        private static void HttpMsgEvent(string msg) {
            Console.WriteLine($"msg:{msg}");
            _socket.Send("OK");
        }

    }

 

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

namespace test.Framework {
    public class Httplistener : IDisposable {

        public delegate void HttpDeletegate(string str);
        public event HttpDeletegate HttpEvent;

        public HttpListener SSocket;
        public string Senddata = "";

        public Httplistener() {

            SSocket = new HttpListener();
        }

        public bool Send(string s) {
            Senddata = s;
            return true;

        }

        public void Dispose() {
            if (SSocket != null) Stop();

        }

        public void Stop() {

            SSocket.Stop();
        }

        public bool IsSupported() {

            return HttpListener.IsSupported;
        }

        public bool Start(string url = "") {
            if (SSocket == null) return false;
            if (string.IsNullOrWhiteSpace(url)) return false;
            if (!IsSupported()) return false;

            //SSocket.Prefixes.Add("http://+:8080/POST/");
            SSocket?.Prefixes.Add(url);
            SSocket?.Start();
            SSocket?.BeginGetContext(Receive, null);//异步监听客户端请求

            Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss:fff}:初始化完成,等待请求\r\n");

            return true;

        }

        /// <summary>
        /// 异步监听
        /// </summary>
        /// <param name="ar"></param>
        private void Receive(IAsyncResult ar) {

            //继续异步监听
            SSocket.BeginGetContext(Receive, null);

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss:fff}:新请求");

            var context = SSocket.EndGetContext(ar); //获得context对象

            var request = context.Request;
            var response = context.Response;

            Console.WriteLine("{0} {1} HTTP/1.1", request.HttpMethod, request.RawUrl);
            Console.WriteLine("Accept: {0}", string.Join(",", request.AcceptTypes));
            Console.WriteLine("User-Agent: {0}", request.UserAgent);
            Console.WriteLine("Accept-Encoding: {0}", request.Headers["Accept-Encoding"]);
            Console.WriteLine("Connection: {0}", request.KeepAlive ? "Keep-Alive" : "close");
            Console.WriteLine("Host: {0}", request.Url);
            Console.WriteLine("RemoteEndPoint: {0}", request.RemoteEndPoint);
            ;
            var result = "";
            var isReceive = Receivedata(request, response);

            if (!isReceive) {
                result = "error";
            } else {

                var sendExpire = DateTime.Now.Ticks + 30000 * 10000;
                for (; DateTime.Now.Ticks < sendExpire; Thread.Sleep(20)) if (Senddata.Length >= 0) break;

                result = Senddata;
                Senddata = "";
            }

            Console.WriteLine($"SEND:{result}");

            Send(200, result, response);

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss:fff}:处理完成\r\n");
        }

        /// <summary>
        /// //接收数据
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        private bool Receivedata(HttpListenerRequest request, HttpListenerResponse response) {
            string data;

            try {
                var byteList = new List<byte>();
                var byteArr = new byte[2048];
                int readLen;
                var len = 0;

                do {
                    readLen = request.InputStream.Read(byteArr, 0, byteArr.Length);
                    len += readLen;
                    byteList.AddRange(byteArr);
                } while (readLen != 0);

                data = Encoding.UTF8.GetString(byteList.ToArray(), 0, len);

                HttpEvent?.Invoke(data); //触发事件

            } catch (Exception ex) {

                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"ERROR:{ex}");
                Send(404, ex.Message, response);
                return false;
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"RECV:{data.Trim()}");

            return true;
        }

        private void Send(int code, string data, HttpListenerResponse response) {

            response.ContentType = "text/plain;charset=UTF-8";
            response.AddHeader("Content-type", "text/plain");
            response.ContentEncoding = Encoding.UTF8;
            //response.StatusDescription = code.ToString();
            response.StatusCode = code;

            var returnByteArr = Encoding.UTF8.GetBytes(data);
            try {
                using (var stream = response.OutputStream) { stream.Write(returnByteArr, 0, returnByteArr.Length); }
            } catch (Exception ex) {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"ERROR:{ex}");
            }

        }

    }
}
 

参考【https://www.cnblogs.com/yijiayi/p/9867502.html

参考【https://www.cnblogs.com/TianFang/archive/2007/01/03/610636.html

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值