通过HttpListener实现简单的Http服务

203 篇文章 3 订阅
203 篇文章 0 订阅

通过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 ======

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using DevSDK.Net.Sockets;
using System.IO;


namespace ConsoleApplication1
{
    class Program
    {
        static HttpListener sSocket = null;
        
        static void Main(string[] args)
        {
            sSocket = new HttpListener();
            sSocket.Prefixes.Add("http://127.0.0.1:8080/");
            sSocket.Start();
            sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);
            Console.Read();            
        }

        static void GetContextCallBack(IAsyncResult ar)
        {
            try
            {
                sSocket = ar.AsyncState as HttpListener;
                HttpListenerContext context = sSocket.EndGetContext(ar);
   sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);
   
                Console.WriteLine(context.Request.Url.PathAndQuery);
				
	       //其它处理code
            }
            catch { }           
        }
    }
}


非异步方法listener


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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
using System.Threading;
using System.Web;
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                HttpListener listerner = new HttpListener();
                {
                    for (; true; )
                    {
                        try
                        {
                            listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问
                            listerner.Prefixes.Add("http://192.168.1.10:1500/ApiService/");

                            listerner.Start();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("未能成功连接服务器.....");
                            listerner = new HttpListener();
                            continue;
                        }
                        break;
                    }
                    Console.WriteLine("服务器启动成功.......");

                    int maxThreadNum, portThreadNum;

                    //线程池
                    int minThreadNum;
                    ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
                    ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
                    Console.WriteLine("最大线程数:{0}", maxThreadNum);
                    Console.WriteLine("最小空闲线程数:{0}", minThreadNum);

					Console.WriteLine("\n\n等待客户连接中。。。。"); while (true) { //等待请求连接 //没有请求则GetContext处于阻塞状态 HttpListenerContext ctx = listerner.GetContext(); ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), ctx); } con.Close(); listerner.Stop(); } } catch (Exception e) { Console.WriteLine(e.Message); Console.Write("Press any key to continue . . . "); Console.ReadKey( ); } } static void TaskProc(object obj) { HttpListenerContext ctx = (HttpListenerContext)obj; ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码 string type = ctx.Request.QueryString["type"]; string userId = ctx.Request.QueryString["userId"]; string password = ctx.Request.QueryString["password"]; string filename = Path.GetFileName(ctx.Request.RawUrl); string userName = HttpUtility.ParseQueryString(filename).Get("userName");//避免中文乱码 
					
					接收POST参数
					//var client = obj as HttpListenerContext;
					//var request = client.Request;

					//Stream stream = request.InputStream;
					//System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8);
					//String body = reader.ReadToEnd();
					//Console.WriteLine("收到POST数据:" + HttpUtility.UrlDecode(body));

					//进行处理 //使用Writer输出http响应代码 
					using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream)) 
					{ 
						writer.Write(“处理结果”); 
						writer.Close(); 
						ctx.Response.Close(); 
					} 
				} 
			}
		}


Android客户端:
public static void Register(final Handler handler, final Context context,
final String userId, final String userName,final int groupId, final String password){
new Thread(new Runnable(){
       public void run() {
        if(!CommonTools.checkNetwork(context)){
        Message msg = new Message();
        msg.what = Signal.NETWORK_ERR;
        handler.sendMessage(msg);
        return;
        }
       
        try {  
        String content = "";
        String tmp   =   java.net.URLEncoder.encode(userName,   "utf-8");   //防止中文乱码
        URL url = new URL(URL+"?type=Register&userId="+userId+"&password="+password+"&groupId="+groupId+"&userName="+tmp);   
               // HttpURLConnection   
               HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();   
     
               if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {   
                     
                   InputStreamReader isr = new InputStreamReader(httpconn.getInputStream(), "utf-8");   
                   int i;   
                      
                   // read   
                   while ((i = isr.read()) != -1) {   
                       content = content + (char) i;   
                   }   
                   isr.close();     
               }   
               //disconnect   
               httpconn.disconnect();   


    } catch (Exception e) {
    e.printStackTrace();
    }
       }//run
}).start();//thread
}


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

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


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

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;


namespace HttpHelper
{
    /// <summary>
    /// HTTP请求监听
    /// </summary>
    public class HttpListeners 
    {
        private static HttpListener _httpListener;
        static readonly int Port = 1005;
        static HttpListeners()
        {
            ListenerStart();
        }

        private static bool ListenerStop()
        {
            try
            {
                if (_httpListener != null)
                {
                    //LogInfo("停止监听端口:" + Port);
                    _httpListener.Stop();
                }
                return true;
            }
            catch (Exception e)
            {
                //LogError(e.Message + e.StackTrace);
                return false;
            }
        }


        /// <summary>
        /// 监听端口
        /// </summary>
        private static void ListenerStart()
        {
            try
            {
                _httpListener = new HttpListener { AuthenticationSchemes = AuthenticationSchemes.Anonymous };
                _httpListener.Prefixes.Add(string.Format("http://+:{0}/",Port));
                _httpListener.Start();
                //LogInfo("开始监听端口:" + Port);
                while (true)
                {
                    try
                    {
                        //监听客户端的连接,线程阻塞,直到有客户端连接为止
                        var client = _httpListener.GetContext();
                        new Thread(HandleRequest).StartAsync(client);
                    }
                    catch (Exception ex)
                    {
                        //LogError(ex.Message + ex.StackTrace);
                    }
                }
            }
            catch (Exception e)
            {
                //LogError(e.Message + e.StackTrace);
                Environment.Exit(0);
            }
        }

        private static void HandleRequest(object obj)
        {
            var client = obj as HttpListenerContext;
            if (client == null) return;
            try
            {
                var coding = Encoding.UTF8;
                var request = client.Request;
                // 取得回应对象
                var response = client.Response;
                response.StatusCode = 200;
                response.ContentEncoding = coding;

                Console.WriteLine("{0} {1} HTTP/1.1", request.HttpMethod, request.RawUrl);
                Console.WriteLine("Accept: {0}", string.Join(",", request.AcceptTypes));
                Console.WriteLine("Accept-Language: {0}",
                    string.Join(",", request.UserLanguages));
                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.UserHostName);
                Console.WriteLine("Pragma: {0}", request.Headers["Pragma"]);
                
                // 构造回应内容
                string responseString = @"<html><head><title>HttpListener Test</title></head><body><div>Hello, world.</div></body></html>";


                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
                //对客户端输出相应信息.
                response.ContentLength64 = buffer.Length;
                Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                //关闭输出流,释放相应资源
                output.Close();
            }
            catch (Exception e)
            {
                //LogError(e.Message + e.StackTrace);
            }
            finally
            {
                try
                {
                    client.Response.Close();
                }
                catch (Exception e)
                {
                    //LogError(e.Message);
                }
            }
        }
    }
}


=== ThreadHelper ===
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace HttpHelper
{
    public static class ThreadHelper
    {
        /// <summary>
        /// 开启同步多线程
        /// </summary>
        public static void StartSync(this IEnumerable<Thread> threads, object startPara = null, Func<object, object> callback = null)
        {
            var ts = threads.ToArray();
            //启动线程
            foreach (var thread in ts)
            {
                if (!thread.IsBackground)
                {
                    thread.IsBackground = true;
                }
                var times = 0;
                while (thread.ThreadState == (ThreadState.Background | ThreadState.Unstarted) && times < 10)
                {
                    try
                    {
                        if (startPara == null)
                        {
                            thread.Start();
                        }
                        else
                        {
                            thread.Start(startPara);
                        }
                    }
                    catch (Exception e)
                    {
                        times++;        
                    }
                    Thread.Sleep(100);
                }
            }
            Thread.Sleep(2000);
            //等待全部结束
            foreach (var thread in ts)
            {
                try
                {
                    thread.Join();
                }
                catch (Exception e)
                {
                }
            }
            if (callback != null)
            {
                callback(startPara);
            }
        }


        /// <summary>
        /// 开启多线程
        /// </summary>
        public static void StartAsync(this IEnumerable<Thread> threads, object startPara = null, Func<object, object> callback = null)
        {
            var ts = threads.ToArray();
            //启动线程
            foreach (var thread in ts)
            {
                if (!thread.IsBackground)
                {
                    thread.IsBackground = true;
                }
                var times = 0;
                while (thread.ThreadState == (ThreadState.Background | ThreadState.Unstarted) && times < 10)
                {
                    try
                    {
                        if (startPara == null)
                        {
                            thread.Start();
                        }
                        else
                        {
                            thread.Start(startPara);
                        }
                    }
                    catch (Exception e)
                    {
                        times++;
                    }
                    Thread.Sleep(100);
                }
            }
            if (callback != null)
            {
                callback(startPara);
            }
        }


        /// <summary>
        /// 开启同步线程
        /// </summary>
        public static void StartSync(this Thread thread, object parameter = null)
        {
            try
            {
                if (!thread.IsBackground)
                {
                    thread.IsBackground = true;
                }
                if (parameter == null)
                {
                    thread.Start();
                }
                else
                {
                    thread.Start(parameter);
                }
            }
            catch (Exception e)
            {
            }
            Thread.Sleep(1000);
            try
            {
                thread.Join();
            }
            catch (Exception e)
            {
            }
        }


        /// <summary>
        /// 开启带超时的同步线程
        /// </summary>
        public static void StartSyncTimeout(this Thread thread, int timeoutSeconds, object parameter = null)
        {
            try
            {
                if (!thread.IsBackground)
                {
                    thread.IsBackground = true;
                }
                if (parameter == null)
                {
                    thread.Start();
                }
                else
                {
                    thread.Start(parameter);
                }
                thread.Join(timeoutSeconds * 1000);
            }
            catch (Exception e)
            {
            }
        }


        /// <summary>
        /// 开启异步线程
        /// </summary>
        public static void StartAsync(this Thread thread, object parameter = null)
        {
            try
            {
                if (!thread.IsBackground)
                {
                    thread.IsBackground = true;
                }
                if (parameter == null)
                {
                    thread.Start();
                }
                else
                {
                    thread.Start(parameter);
                }
            }
            catch (Exception e)
            {
            }
        }
    }
}

=== end ===


=== end ===


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值