c#原始提供了http的监听的类HttpListener,实现了简单的http。文章地址《C# 控制台或者winform程序开启http的监听状态》

但是经过我测试,这个HttpListener提供的真的就只是简单的http监听功能,无法实现高并发处理。

不知道是我处理问题还是其他什么原因,无法实现,当上一个http请求连接尚未关闭的情况下,即便是把请求放到另外一个线程执行,都要等到处理结束,close了才能接受和处理下一次的连接请求。

也许你会说HttpListener不是提供了异步监听的嘛?异步不就可以类使用多线程实现嘛。但是经过我测试,确实没有得到我想要的实际效果。

所以另辟蹊径。http其实质就是socket的tcp封装实现的功能,单次请求,处理,关闭的socket功能。

所以这里找到了可以使用最原始的socket的来提供http监听,处理数据,关闭状态。

好了直接上代码,,一下代码部分来至于博客园,园友帖子提供,时间久远亦不知道是哪位仁兄的帖子,见谅。

   internal class HttpServer
     {
         private IPEndPoint _IP;
         private TcpListener _Listeners;
         private volatile bool IsInit = false;
         HashSet<string> Names;

         /// <summary>
         /// 初始化服务器
         /// </summary>
         public HttpServer(string ip, int port, HashSet<string> names)
         {
             IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port);
             this._IP = localEP;
             Names = names;
             if (Names == null)
             {
                 Names = new HashSet<string>();
             }
             try
             {
                 foreach (var item in names)
                 {
                     Console.WriteLine(string.Format(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff:") + "Start Listen Http Socket -> {0}:{1}{2} ", ip, port, item));
                 }
                 this._Listeners = new TcpListener(IPAddress.Parse(ip), port);
                 );
                 IsInit = true;
                 this.AcceptAsync();
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex);
                 this.Dispose();
             }
         }

         private void AcceptAsync()
         {
             try
             {
                 this._Listeners.BeginAcceptTcpClient(new AsyncCallback(AcceptAsync_Async), null);
             }
             catch (Exception) { }
         }

         private void AcceptAsync_Async(IAsyncResult iar)
         {
             this.AcceptAsync();
             try
             {
                 TcpClient client = this._Listeners.EndAcceptTcpClient(iar);
                 var socket = new HttpClient(client);
                 Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff:") + "Create Http Socket Remote Socket LocalEndPoint:" + client.Client.LocalEndPoint + " RemoteEndPoint:" + client.Client.RemoteEndPoint.ToString());
                 foreach (var item in Names)
                 {
                     if (socket.http_url.StartsWith(item))
                     {
                         try
                         {
                             socket.process();
                             return;
                         }
                         catch { break; }
                     }
                 }
                 socket.WriteFailure();
                 socket.Close();
             }
             catch (Exception) { }
         }

         /// <summary>
         /// 释放资源
         /// </summary>
         public void Dispose()
         {
             if (IsInit)
             {
                 IsInit = false;
                 this.Dispose(true);
                 GC.SuppressFinalize(this);
             }
         }

         /// <summary>
         /// 释放所占用的资源
         /// </summary>
         /// <param name="flag1"></param>
         protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)
         {
             if (flag1)
             {
                 if (_Listeners != null)
                 {
                     try
                     {
                         Console.WriteLine(string.Format("Stop Http Listener -> {0}:{1} ", this.IP.Address.ToString(), this.IP.Port));
                         _Listeners.Stop();
                         _Listeners = null;
                     }
                     catch { }
                 }
             }
         }

         /// <summary>
         /// 获取绑定终结点
         /// </summary>
         public IPEndPoint IP { get { return this._IP; } }
     }

这个是实现socket监听状态

  public class HttpClient
     {
          *  * ; // 10MB
         ;
         private Stream inputStream;
         public StreamWriter OutputStream;
         public String http_method;
         public String http_url;
         public String http_protocol_versionstring;
         public Hashtable httpHeaders = new Hashtable();
         internal TcpClient _Socket;

         /// <summary>
         /// 这个是服务器收到有效链接初始化
         /// </summary>
         internal HttpClient(TcpClient client)
         {
             this._Socket = client;
             inputStream = new BufferedStream(_Socket.GetStream());
             OutputStream = new StreamWriter(new BufferedStream(_Socket.GetStream()), UTF8Encoding.Default);
             ParseRequest();
         }

         internal void process()
         {
             try
             {
                 if (http_method.Equals("GET"))
                 {
                     Program.Pool.ActiveHttp(this, GetRequestExec());
                 }
                 else if (http_method.Equals("POST"))
                 {
                     Program.Pool.ActiveHttp(this, PostRequestExec());
                 }
             }
             catch (Exception e)
             {
                 Console.WriteLine("Exception: " + e.ToString());
                 WriteFailure();
             }
         }

         public void Close()
         {
             OutputStream.Flush();
             inputStream.Dispose();
             inputStream = null;
             OutputStream.Dispose();
             OutputStream = null; // bs = null;
             this._Socket.Close();
         }

         #region 读取流的一行 private string ReadLine()
         /// <summary>
         /// 读取流的一行
         /// </summary>
         /// <returns></returns>
         private string ReadLine()
         {
             int next_char;
             string data = "";
             while (true)
             {
                 next_char = this.inputStream.ReadByte();
                 if (next_char == '\n') { break; }
                 if (next_char == '\r') { continue; }
                 ) { Thread.Sleep(); continue; };
                 data += Convert.ToChar(next_char);
             }
             return data;
         }
         #endregion

         #region 转化出 Request private void ParseRequest()
         /// <summary>
         /// 转化出 Request
         /// </summary>
         private void ParseRequest()
         {
             String request = ReadLine();
             if (request != null)
             {
                 string[] tokens = request.Split(' ');
                 )
                 {
                     throw new Exception("invalid http request line");
                 }
                 http_method = tokens[].ToUpper();
                 http_url = tokens[];
                 http_protocol_versionstring = tokens[];
             }
             String line;
             while ((line = ReadLine()) != null)
             {
                 if (line.Equals(""))
                 {
                     break;
                 }
                 int separator = line.IndexOf(':');
                 )
                 {
                     throw new Exception("invalid http header line: " + line);
                 }
                 String name = line.Substring(, separator);
                 ;
                 while ((pos < line.Length) && (line[pos] == ' '))
                 {
                     pos++;//过滤键值对的空格
                 }
                 string value = line.Substring(pos, line.Length - pos);
                 httpHeaders[name] = value;
             }
         }
         #endregion

         #region 读取Get数据 private Dictionary<string, string> GetRequestExec()
         /// <summary>
         /// 读取Get数据
         /// </summary>
         /// <returns></returns>
         private Dictionary<string, string> GetRequestExec()
         {
             Dictionary<string, string> datas = new Dictionary<string, string>();
             );
             )
             {
                 );
                 datas = getData(data);
             }
             WriteSuccess();
             return datas;
         }
         #endregion

         #region 读取提交的数据 private void handlePOSTRequest()
         /// <summary>
         /// 读取提交的数据
         /// </summary>
         private Dictionary<string, string> PostRequestExec()
         {
             ;
             MemoryStream ms = new MemoryStream();
             if (this.httpHeaders.ContainsKey("Content-Length"))
             {
                 //内容的长度
                 content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);
                 if (content_len > MAX_POST_SIZE) { throw new Exception(String.Format("POST Content-Length({0}) 对于这个简单的服务器太大", content_len)); }
                 byte[] buf = new byte[BUF_SIZE];
                 int to_read = content_len;
                 )
                 {
                     , Math.Min(BUF_SIZE, to_read));
                     )
                     {
                         ) { break; }
                         else { throw new Exception("client disconnected during post"); }
                     }
                     to_read -= numread;
                     ms.Write(buf, , numread);
                 }
                 ms.Seek(, SeekOrigin.Begin);
             }
             WriteSuccess();
             StreamReader inputData = new StreamReader(ms);
             string data = inputData.ReadToEnd();
             return getData(data);
         }
         #endregion

         #region 输出状态
         /// <summary>
         /// 输出200状态
         /// </summary>
         public void WriteSuccess()
         {
             OutputStream.WriteLine("HTTP/1.0 200 OK");
             OutputStream.WriteLine("Content-Type: text/html");
             OutputStream.WriteLine("Connection: close");
             OutputStream.WriteLine("");
         }

         /// <summary>
         /// 输出状态404
         /// </summary>
         public void WriteFailure()
         {
             OutputStream.WriteLine("HTTP/1.0 404 File not found");
             OutputStream.WriteLine("Content-Type: text/html");
             OutputStream.WriteLine("Connection: close");
             OutputStream.WriteLine("");
         }
         #endregion

         /// <summary>
         /// 分析http提交数据分割
         /// </summary>
         /// <param name="rawData"></param>
         /// <returns></returns>
         private static Dictionary<string, string> getData(string rawData)
         {
             var rets = new Dictionary<string, string>();
             string[] rawParams = rawData.Split('&');
             foreach (string param in rawParams)
             {
                 string[] kvPair = param.Split('=');
                 ];
                 ]);
                 rets[key] = value;
             }
             return rets;
         }
     }

实现了对http数据请求处理

 public interface ISocketPool
     {
         /// <summary>
         ///
         /// </summary>
         /// <param name="client"></param>
         void ActiveHttp(Fly.Network.SocketPool.Http.HttpClient client, Dictionary<string, string> parms);
     }
 public class Program
     {
         public static MessagePool Pool = new MessagePool();
         static void Main(string[] args)
         {
             HttpServer https = , new HashSet<string>() {"/test/","/flie/" });
             Console.ReadLine();
         }
     }
     class MessagePool : ISocketPool
     {
         public void ActiveHttp(HttpClient client, Dictionary<string, string> parms)
         {
             Thread.Sleep(, ));
             foreach (var item in parms)
             {
                 Console.WriteLine(DateTime.Now.NowString() + "item.Key:" + item.Key + "; item.Value:" + item.Value);
             }
             string strHtml = @"
 <html><head></head>
 <body>
 <div>&nbsp;</div>
 <div>&nbsp;</div>
 <div>&nbsp;</div>
 <div>&nbsp;</div>
 <div>&nbsp;</div>
 {0}
 </body>
 </html>
 ";
             client.OutputStream.WriteLine(string.Format(strHtml, DateTime.Now.NowString() + "xxxxxxxxxxx"));
             client.Close();
         }
     }

程序启动过后,看到输出

-- ::::Start Listen Http Socket -> /test/
-- ::::Start Listen Http Socket -> /flie/

接下来我们在浏览器输入 127.0.0.1/test/

正常收到请求,输出程序

127.0.0.1/test/

这里test1这个并不是我们监听饿目录,根本不会处理,

接下来我们再看看这个效果 get提交的参数 127.0.0.1/test/?bb=test

输出了get提交过来的参数信息。可能你会奇怪,为什么一次请求会收到两次连接请求。这里我查看过了其中一次请求是浏览器自带的请求页面标签的icon连接请求,

如果你拷贝了程序,你现在可以实现跑来程序,然后输入网址,按着F5不放,看看服务器的承受能力,当然这里忽律了逻辑方面对cpu内存消耗和时间消耗问题。

测试看看吧。

C# 利用socekt做到http监听,怎么样才能做到高性能的更多相关文章

  1. 利用Node的chokidar 监听文件改变的文件。

    最近维护一个项目.每次改完东西,都要上传到服务器.然后有时候就忘记一些东西,于是就想有没有可以方法能监听文件的改变.然后我再利用程序把更改的文件一键上传到服务器. 于是就找到了nodejs 的chok ...

  2. 利用spring的ApplicationListener监听某一类事件的发生

    1.ApplicationListener在使用过程中可以监听某一事件的发生,可以做出相应的处理,这个方式不常用,但是在特殊情况下面还是有用的. 2.导包pom.xml <project xml ...

  3. android菜鸟学习笔记23----ContentProvider(三)利用内置ContentProvider监听短信及查看联系人

    要使用一个ContentProvider,必须要知道的是它所能匹配的Uri及其数据存储的表的结构. 首先想办法找到访问短信及联系人数据的ContentProvider能接受的Uri: 到github上 ...

  4. 利用input事件来监听移动端的输入

    今天遇到一个新需求,经理要求评论功能需要限制字数,就像微博那样限制最多输入150字,这里就需要实时提醒用户还能输入多少字了. 在最开始的时候,想到的是监听keyup事件,然后计算用户输入的字数,但是有 ...

  5. 利用bootstrap制作滚动监听

    滚动监听(Scrollspy)插件,即自动更新导航插件,会根据滚动条的位置自动更新对应的导航目标. 在这里,需要引入三个文件:bootstrap.min.css      jquery-3.3.1.j ...

  6. 20180530利用Maxwell组件实时监听Mysql的binlog日志

    转自:https://blog.csdn.net/qq_30921461/article/details/78320750 http://kafka.apache.org/quickstart htt ...

  7. 利用input event 实时监听input输入的内容

    <div id="addNumber"> <p>How many people would you like to invite?</p> &l ...

  8. 利用原生JS实时监听input框输入值

    传送门https://www.cnblogs.com/lantinggumo/p/7636715.html 传送门https://www.cnblogs.com/nailc/p/8572226.htm ...

  9. Android监听手机网络变化

    Android监听手机网络变化 手机网络状态发生变化会发送广播,利用广播接收者,监听手机网络变化 效果图 注册广播接收者 <?xml version="1.0" encodi ...

随机推荐

  1. 5.Powershell变量

    在指令执行过程中,会有一些数据产生,这些数据被用于以后的语句,需要一个存储单元暂时的存放这些数据,这个时候定义一个变量来存储数据.例如$string = “Hello Powershell!” Pow ...

  2. VS快捷键总结(包括ReSharper)

    Shift+Alt+Enter 全屏显示代码Ctrl+E 最近文件列表Ctrl+B 转到定义Ctrl+Alt+B 转到继承类或接口处Ctrl+U 转到基类Ctrl+D 复制当前行或选定的块(Dupli ...

  3. CYQ.Data V5 MDataTable 专属篇介绍

    前言 以前一两个月才出一篇,这三天有点变态地连续1天1篇(其实都是上周末两天写好的存货). 短期应该没有新的和此框架相关的文章要写了,这应该是最后一篇,大伙且看且珍惜. 前两篇讲数据库读写分离和分布式 ...

  4. 开源消息队列:NetMQ

    NetMQ 是  ZeroMQ的C#移植版本. ZeroMQ是一个轻量级的消息内核,它是对标准socket接口的扩展.它提供了一种异步消息队列,多消息模式,消息过滤(订阅),对多种传输协议的无缝访问. ...

  5. Unity3D游戏开发初探—3.初步了解U3D物理引擎

    一.什么是物理引擎? 四个世纪前,物理学家牛顿发现了万有引力,并延伸出三大牛顿定理,为之后的物理学界的发展奠定了强大的理论基础.牛顿有句话是这么说的:“如果说我看得比较远的话,那是因为我站在巨人的肩膀 ...

  6. 备忘录--关于线程和IO知识

    因为自己还在出差中,没时间深入学习,最近工作里又有对一些技术的思考,所以这里记录下来,等回去有时间可以按照这个思路进行学习,这里主要起到备忘的作用. 1.线程难学难在我们没有理解操作系统里的线程设计机 ...

  7. 使用ViewPager+Fragment实现选项卡切换效果

    实现效果 本实例主要实现用ViewPage和Fragment实现选项卡切换效果,选项卡个数为3个,点击选项卡或滑动屏幕会切换Fragment并实现选项卡下方下边框条跟随移动效果. 本程序用androi ...

  8. 前端构建工具gulpjs的使用介绍及技巧

    gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速 ...

  9. 一次 Oracle 算出运算溢出问题 排查解决 (并非除数为零!)

    前段时间 出现过这个问题,: 表中有一列为number类型 rec_recordlength (两个时间的间隔长度/秒) 部分数据 统计这个字段就会出现 "算出运算溢出" 错误,很 ...

  10. OO设计原则

    开闭原则(OCP) 里氏代换原则(LSP) 依赖倒转原则(DIP) 接口隔离原则(ISP) 合成/聚合利用原则(CARP) 迪米特法则(LOD)