.NET下通过HttpListener实现简单的Http服务

时间:2022-09-09 18:01:09

HttpListener提供一个简单的、可通过编程方式控制的 HTTP 协议侦听器.使用它可以很容易的提供一些Http服务,而无需启动IIS这类大型服务程序。使用HttpListener的方法流程很简单:主要分为以下几步 

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

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

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

4.处理客户端的Http请求 

5.关闭HTTP侦听器 

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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, 0, (int)fs.Length); //将文件读到缓存区
       request.Response.StatusCode = 200;
       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, 0, buffer.Length);  //将缓存区的字节数写入当前请求流返回
       output.Close();
      }
     }));
     subthread.Start(requestContext); //开启处理线程处理下载文件
    }
    catch (Exception ex)
    {
     try
     {
      requestContext.Response.StatusCode = 500;
      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, 0, 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 = 200;
      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, 0, buffer.Length);
      output.Close();
     }));
     subthread.Start(requestContext); //开启处理线程处理下载文件
    }
    catch (Exception ex)
    {
     try
     {
      requestContext.Response.StatusCode = 500;
      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, 0, buffer.Length);
      //关闭输出流,释放相应资源
      output.Close();
     }
     catch { }
    }
   }
  }
 }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace HttpListenerApp
{
 class Program
 {
  static void Main(string[] args)
  {
   //开启请求监听
   HttpProvider.Init();
  }
 }
}

执行后的结果为:

.NET下通过HttpListener实现简单的Http服务

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。