zoukankan      html  css  js  c++  java
  • 通过HttpListener实现简单的Http服务

    通过HttpListener实现简单的Http服务

    通过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();

    初始化需要经过如下两步

    添加需要监听的URL范围至listener.Prefixes中,可以通过如下函数实现:
    listener.Prefixes.Add(prefix)    //prefix必须以'/'结尾
    调用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()函数即可关闭侦听器,并释放相关资源

    异步方法listener


    ====== 异步方法listener ======

    [csharp] view plain copy
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Net;  
    6. using System.Net.Sockets;  
    7. using DevSDK.Net.Sockets;  
    8. using System.IO;  
    9.   
    10.   
    11. namespace ConsoleApplication1  
    12. {  
    13.     class Program  
    14.     {  
    15.         static HttpListener sSocket = null;  
    16.           
    17.         static void Main(string[] args)  
    18.         {  
    19.             sSocket = new HttpListener();  
    20.             sSocket.Prefixes.Add("http://127.0.0.1:8080/");  
    21.             sSocket.Start();  
    22.             sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);  
    23.             Console.Read();              
    24.         }  
    25.   
    26.         static void GetContextCallBack(IAsyncResult ar)  
    27.         {  
    28.             try  
    29.             {  
    30.                 sSocket = ar.AsyncState as HttpListener;  
    31.                 HttpListenerContext context = sSocket.EndGetContext(ar);  
    32.    sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);  
    33.      
    34.                 Console.WriteLine(context.Request.Url.PathAndQuery);  
    35.                   
    36.            //其它处理code  
    37.             }  
    38.             catch { }             
    39.         }  
    40.     }  
    41. }  

    非异步方法listener


    ====== C# 利用HttpListener监听处理Http请求 ======

    [csharp] view plain copy
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Net;  
    6. using System.Net.Sockets;  
    7. using System.IO;  
    8. using System.Xml.Serialization;  
    9. using System.Threading;  
    10. using System.Web;  
    11. namespace Test  
    12. {  
    13.     class Program  
    14.     {  
    15.         static void Main(string[] args)  
    16.         {  
    17.             try  
    18.             {  
    19.                 HttpListener listerner = new HttpListener();  
    20.                 {  
    21.                     for (; true; )  
    22.                     {  
    23.                         try  
    24.                         {  
    25.                             listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问  
    26.                             listerner.Prefixes.Add("http://192.168.1.10:1500/ApiService/");  
    27.   
    28.                             listerner.Start();  
    29.                         }  
    30.                         catch (Exception e)  
    31.                         {  
    32.                             Console.WriteLine("未能成功连接服务器.....");  
    33.                             listerner = new HttpListener();  
    34.                             continue;  
    35.                         }  
    36.                         break;  
    37.                     }  
    38.                     Console.WriteLine("服务器启动成功.......");  
    39.   
    40.                     int maxThreadNum, portThreadNum;  
    41.   
    42.                     //线程池  
    43.                     int minThreadNum;  
    44.                     ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);  
    45.                     ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);  
    46.                     Console.WriteLine("最大线程数:{0}", maxThreadNum);  
    47.                     Console.WriteLine("最小空闲线程数:{0}", minThreadNum);  
    48.                       
    49.                     Console.WriteLine(" 等待客户连接中。。。。");  
    50.                     while (true)  
    51.                     {  
    52.                         //等待请求连接  
    53.                         //没有请求则GetContext处于阻塞状态  
    54.                         HttpListenerContext ctx = listerner.GetContext();  
    55.   
    56.                         ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), ctx);  
    57.                     }  
    58.                     con.Close();  
    59.                     listerner.Stop();  
    60.                 }  
    61.             }  
    62.             catch (Exception e)  
    63.             {  
    64.                 Console.WriteLine(e.Message);  
    65.                 Console.Write("Press any key to continue . . . ");  
    66.                 Console.ReadKey( );  
    67.             }  
    68.         }  
    69.   
    70.         static void TaskProc(object o)  
    71.         {  
    72.             HttpListenerContext ctx = (HttpListenerContext)o;  
    73.   
    74.             ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码  
    75.          
    76.             string type = ctx.Request.QueryString["type"];  
    77.             string userId = ctx.Request.QueryString["userId"];  
    78.             string password = ctx.Request.QueryString["password"];  
    79.             string filename = Path.GetFileName(ctx.Request.RawUrl);  
    80.             string userName = HttpUtility.ParseQueryString(filename).Get("userName");//避免中文乱码  
    81.   
    82.             //进行处理  
    83.               
    84.             //使用Writer输出http响应代码  
    85.             using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))  
    86.             {  
    87.                 writer.Write(“处理结果”);  
    88.                 writer.Close();  
    89.                 ctx.Response.Close();  
    90.             }  
    91.         }  
    92.     }  
    93. }  



    Android客户端:

    [java] view plain copy
     
    1. public static void Register(final Handler handler, final Context context,  
    2. final String userId, final String userName,final int groupId, final String password){  
    3. new Thread(new Runnable(){  
    4.        public void run() {  
    5.         if(!CommonTools.checkNetwork(context)){  
    6.         Message msg = new Message();  
    7.         msg.what = Signal.NETWORK_ERR;  
    8.         handler.sendMessage(msg);  
    9.         return;  
    10.         }  
    11.          
    12.         try {    
    13.         String content = "";  
    14.         String tmp   =   java.net.URLEncoder.encode(userName,   "utf-8");   //防止中文乱码  
    15.         URL url = new URL(URL+"?type=Register&userId="+userId+"&password="+password+"&groupId="+groupId+"&userName="+tmp);     
    16.                // HttpURLConnection     
    17.                HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();     
    18.        
    19.                if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {     
    20.                        
    21.                    InputStreamReader isr = new InputStreamReader(httpconn.getInputStream(), "utf-8");     
    22.                    int i;     
    23.                         
    24.                    // read     
    25.                    while ((i = isr.read()) != -1) {     
    26.                        content = content + (char) i;     
    27.                    }     
    28.                    isr.close();       
    29.                }     
    30.                //disconnect     
    31.                httpconn.disconnect();     
    32.   
    33.   
    34.     } catch (Exception e) {  
    35.     e.printStackTrace();  
    36.     }  
    37.        }//run  
    38. }).start();//thread  
    39. }  



    注意:
    1.中文乱码问题
       在客户端采用如下形式
       String tmp   =   java.net.URLEncoder.encode(userName,   "utf-8");   //防止中文乱码
       服务器端
       string filename = Path.GetFileName(ctx.Request.RawUrl);
       string userName = HttpUtility.ParseQueryString(filename).Get("userName");//避免中文乱码
     
       服务器端需要引入: using System.Web;
       此时可能提示找不到库,则在项目右键添加引用 找到 System.Web.dll勾选即可

    2.[System.Net.HttpListenerException] = {"拒绝访问。"}问题
       如果是win7或者win8,在cmd.exe上右键,以管理员身份运行,然后执行下面的命令
       netsh http add urlacl url=http://本机IP:1500/ user=用户名(如Administrator)

    例:netsh http add urlacl url=http://*:9007/ user=Everyone
       
    3.记得关闭防火墙,或者只开放指定端口,步骤如下:
            step1、点击控制面板
      
      step2、选择windows防火墙,点击高级设置
      
      step3、在弹出的“高级安全windows防火墙”点击“入站规则”,在右侧“操作”栏点击“入站规则”下的“新建规则…”,此时会弹出一个窗口让你设置。剩下的就非常傻瓜化了。
      
      step4、弹出“新建入站规则向导”-规则类型-选中“端口”,点击下一步。选择规则应用的协议“TCP/UDP”如果是TCP你就选择TCP,UDP就选择UDP。再勾选“特定本地端口”在文本框输入您想开放的端口号(例如1521)。
      
      step5、点击下一步,到“连接符合指定条件时应该进行什么操作?”选择“允许连接”。点击下一步到“配置文件”何时应用该规则,勾选“域”、“专用”、“公用”点击下一步。
      
      step6、配置规则名称,随便输入你自己认为好记的规则名称即可。

    非异步方法listener 自开线程处理请求


    ====== 非异步方法listener 自开线程处理请求 ======

    [csharp] view plain copy
     
    1. using System;  
    2. using System.IO;  
    3. using System.Net;  
    4. using System.Text;  
    5. using System.Threading;  
    6.   
    7.   
    8. namespace HttpHelper  
    9. {  
    10.     /// <summary>  
    11.     /// HTTP请求监听  
    12.     /// </summary>  
    13.     public class HttpListeners   
    14.     {  
    15.         private static HttpListener _httpListener;  
    16.         static readonly int Port = 1005;  
    17.         static HttpListeners()  
    18.         {  
    19.             ListenerStart();  
    20.         }  
    21.   
    22.         private static bool ListenerStop()  
    23.         {  
    24.             try  
    25.             {  
    26.                 if (_httpListener != null)  
    27.                 {  
    28.                     //LogInfo("停止监听端口:" + Port);  
    29.                     _httpListener.Stop();  
    30.                 }  
    31.                 return true;  
    32.             }  
    33.             catch (Exception e)  
    34.             {  
    35.                 //LogError(e.Message + e.StackTrace);  
    36.                 return false;  
    37.             }  
    38.         }  
    39.   
    40.   
    41.         /// <summary>  
    42.         /// 监听端口  
    43.         /// </summary>  
    44.         private static void ListenerStart()  
    45.         {  
    46.             try  
    47.             {  
    48.                 _httpListener = new HttpListener { AuthenticationSchemes = AuthenticationSchemes.Anonymous };  
    49.                 _httpListener.Prefixes.Add(string.Format("http://+:{0}/",Port));  
    50.                 _httpListener.Start();  
    51.                 //LogInfo("开始监听端口:" + Port);  
    52.                 while (true)  
    53.                 {  
    54.                     try  
    55.                     {  
    56.                         //监听客户端的连接,线程阻塞,直到有客户端连接为止  
    57.                         var client = _httpListener.GetContext();  
    58.                         new Thread(HandleRequest).StartAsync(client);  
    59.                     }  
    60.                     catch (Exception ex)  
    61.                     {  
    62.                         //LogError(ex.Message + ex.StackTrace);  
    63.                     }  
    64.                 }  
    65.             }  
    66.             catch (Exception e)  
    67.             {  
    68.                 //LogError(e.Message + e.StackTrace);  
    69.                 Environment.Exit(0);  
    70.             }  
    71.         }  
    72.   
    73.         private static void HandleRequest(object obj)  
    74.         {  
    75.             var client = obj as HttpListenerContext;  
    76.             if (client == null) return;  
    77.             try  
    78.             {  
    79.                 var coding = Encoding.UTF8;  
    80.                 var request = client.Request;  
    81.                 // 取得回应对象  
    82.                 var response = client.Response;  
    83.                 response.StatusCode = 200;  
    84.                 response.ContentEncoding = coding;  
    85.   
    86.                 Console.WriteLine("{0} {1} HTTP/1.1", request.HttpMethod, request.RawUrl);  
    87.                 Console.WriteLine("Accept: {0}", string.Join(",", request.AcceptTypes));  
    88.                 Console.WriteLine("Accept-Language: {0}",  
    89.                     string.Join(",", request.UserLanguages));  
    90.                 Console.WriteLine("User-Agent: {0}", request.UserAgent);  
    91.                 Console.WriteLine("Accept-Encoding: {0}", request.Headers["Accept-Encoding"]);  
    92.                 Console.WriteLine("Connection: {0}",  
    93.                     request.KeepAlive ? "Keep-Alive" : "close");  
    94.                 Console.WriteLine("Host: {0}", request.UserHostName);  
    95.                 Console.WriteLine("Pragma: {0}", request.Headers["Pragma"]);  
    96.                   
    97.                 // 构造回应内容  
    98.                 string responseString = @"<html><head><title>HttpListener Test</title></head><body><div>Hello, world.</div></body></html>";  
    99.   
    100.   
    101.                 byte[] buffer = Encoding.UTF8.GetBytes(responseString);  
    102.                 //对客户端输出相应信息.  
    103.                 response.ContentLength64 = buffer.Length;  
    104.                 Stream output = response.OutputStream;  
    105.                 output.Write(buffer, 0, buffer.Length);  
    106.                 //关闭输出流,释放相应资源  
    107.                 output.Close();  
    108.             }  
    109.             catch (Exception e)  
    110.             {  
    111.                 //LogError(e.Message + e.StackTrace);  
    112.             }  
    113.             finally  
    114.             {  
    115.                 try  
    116.                 {  
    117.                     client.Response.Close();  
    118.                 }  
    119.                 catch (Exception e)  
    120.                 {  
    121.                     //LogError(e.Message);  
    122.                 }  
    123.             }  
    124.         }  
    125.     }  
    126. }  



    === ThreadHelper ===

    [csharp] view plain copy
     
      1. using System;  
      2. using System.Collections.Generic;  
      3. using System.Linq;  
      4. using System.Text;  
      5. using System.Threading;  
      6. using System.Threading.Tasks;  
      7.   
      8. namespace HttpHelper  
      9. {  
      10.     public static class ThreadHelper  
      11.     {  
      12.         /// <summary>  
      13.         /// 开启同步多线程  
      14.         /// </summary>  
      15.         public static void StartSync(this IEnumerable<Thread> threads, object startPara = null, Func<object, object> callback = null)  
      16.         {  
      17.             var ts = threads.ToArray();  
      18.             //启动线程  
      19.             foreach (var thread in ts)  
      20.             {  
      21.                 if (!thread.IsBackground)  
      22.                 {  
      23.                     thread.IsBackground = true;  
      24.                 }  
      25.                 var times = 0;  
      26.                 while (thread.ThreadState == (ThreadState.Background | ThreadState.Unstarted) && times < 10)  
      27.                 {  
      28.                     try  
      29.                     {  
      30.                         if (startPara == null)  
      31.                         {  
      32.                             thread.Start();  
      33.                         }  
      34.                         else  
      35.                         {  
      36.                             thread.Start(startPara);  
      37.                         }  
      38.                     }  
      39.                     catch (Exception e)  
      40.                     {  
      41.                         times++;          
      42.                     }  
      43.                     Thread.Sleep(100);  
      44.                 }  
      45.             }  
      46.             Thread.Sleep(2000);  
      47.             //等待全部结束  
      48.             foreach (var thread in ts)  
      49.             {  
      50.                 try  
      51.                 {  
      52.                     thread.Join();  
      53.                 }  
      54.                 catch (Exception e)  
      55.                 {  
      56.                 }  
      57.             }  
      58.             if (callback != null)  
      59.             {  
      60.                 callback(startPara);  
      61.             }  
      62.         }  
      63.   
      64.   
      65.         /// <summary>  
      66.         /// 开启多线程  
      67.         /// </summary>  
      68.         public static void StartAsync(this IEnumerable<Thread> threads, object startPara = null, Func<object, object> callback = null)  
      69.         {  
      70.             var ts = threads.ToArray();  
      71.             //启动线程  
      72.             foreach (var thread in ts)  
      73.             {  
      74.                 if (!thread.IsBackground)  
      75.                 {  
      76.                     thread.IsBackground = true;  
      77.                 }  
      78.                 var times = 0;  
      79.                 while (thread.ThreadState == (ThreadState.Background | ThreadState.Unstarted) && times < 10)  
      80.                 {  
      81.                     try  
      82.                     {  
      83.                         if (startPara == null)  
      84.                         {  
      85.                             thread.Start();  
      86.                         }  
      87.                         else  
      88.                         {  
      89.                             thread.Start(startPara);  
      90.                         }  
      91.                     }  
      92.                     catch (Exception e)  
      93.                     {  
      94.                         times++;  
      95.                     }  
      96.                     Thread.Sleep(100);  
      97.                 }  
      98.             }  
      99.             if (callback != null)  
      100.             {  
      101.                 callback(startPara);  
      102.             }  
      103.         }  
      104.   
      105.   
      106.         /// <summary>  
      107.         /// 开启同步线程  
      108.         /// </summary>  
      109.         public static void StartSync(this Thread thread, object parameter = null)  
      110.         {  
      111.             try  
      112.             {  
      113.                 if (!thread.IsBackground)  
      114.                 {  
      115.                     thread.IsBackground = true;  
      116.                 }  
      117.                 if (parameter == null)  
      118.                 {  
      119.                     thread.Start();  
      120.                 }  
      121.                 else  
      122.                 {  
      123.                     thread.Start(parameter);  
      124.                 }  
      125.             }  
      126.             catch (Exception e)  
      127.             {  
      128.             }  
      129.             Thread.Sleep(1000);  
      130.             try  
      131.             {  
      132.                 thread.Join();  
      133.             }  
      134.             catch (Exception e)  
      135.             {  
      136.             }  
      137.         }  
      138.   
      139.   
      140.         /// <summary>  
      141.         /// 开启带超时的同步线程  
      142.         /// </summary>  
      143.         public static void StartSyncTimeout(this Thread thread, int timeoutSeconds, object parameter = null)  
      144.         {  
      145.             try  
      146.             {  
      147.                 if (!thread.IsBackground)  
      148.                 {  
      149.                     thread.IsBackground = true;  
      150.                 }  
      151.                 if (parameter == null)  
      152.                 {  
      153.                     thread.Start();  
      154.                 }  
      155.                 else  
      156.                 {  
      157.                     thread.Start(parameter);  
      158.                 }  
      159.                 thread.Join(timeoutSeconds * 1000);  
      160.             }  
      161.             catch (Exception e)  
      162.             {  
      163.             }  
      164.         }  
      165.   
      166.   
      167.         /// <summary>  
      168.         /// 开启异步线程  
      169.         /// </summary>  
      170.         public static void StartAsync(this Thread thread, object parameter = null)  
      171.         {  
      172.             try  
      173.             {  
      174.                 if (!thread.IsBackground)  
      175.                 {  
      176.                     thread.IsBackground = true;  
      177.                 }  
      178.                 if (parameter == null)  
      179.                 {  
      180.                     thread.Start();  
      181.                 }  
      182.                 else  
      183.                 {  
      184.                     thread.Start(parameter);  
      185.                 }  
      186.             }  
      187.             catch (Exception e)  
      188.             {  
      189.             }  
      190.         }  
      191.     }  
  • 相关阅读:
    [置顶] 【原创分享】嵌入式linux应用之U-BOOT移植定制篇--20130822
    [置顶] java 连接 mysql 数据库步骤
    [置顶] 【原创】无线LED条屏信息报警项目---2012.05
    用Python正则表达式搜索统计命令行管道中的所有数字
    从SharePoint 2013迁移到SharePoint Online
    SharePoint Framework 构建你的第一个web部件(一)
    SharePoint Framework 配置你的SharePoint客户端web部件开发环境
    SharePoint Framework 配置Office 365开发者租户
    SharePoint Framework 开发工具和库
    SharePoint Framework 概述
  • 原文地址:https://www.cnblogs.com/yuesebote/p/10857466.html
Copyright © 2011-2022 走看看