C# HttpListener简单HTTP服务器需循环启停才能持续收请求的原因
问题根因
这个现象是代码缺陷和浏览器HTTP连接限制共同作用的结果:
- 你贴的实现存在核心的资源泄漏问题:拿到
HttpListenerContext、HttpListenerRequest、HttpListenerResponse对象后,既没有向响应流写入返回内容,也没有执行响应关闭、资源释放操作,和当前请求绑定的TCP连接会一直处于挂起等待状态,不会被回收。 - 运行Angular客户端的浏览器环境对HTTP/1.1请求有同域并发连接数限制,Chrome等主流浏览器对同一源的默认并发TCP连接上限就是2个。前2次请求发出后,2个连接全部被挂起的请求占满,客户端不会再向服务端发起新的请求,后续请求全部在浏览器侧排队,表现为服务端收不到请求。
把
Start()/Stop()放在循环内能跑通属于歪打正着:HttpListener.Stop()会直接强制销毁监听器持有的所有连接资源,中断所有未处理完成的请求,客户端收到连接重置信号后会主动断开连接、释放连接配额,下一轮循环重新启动监听器时就能接入新请求。但这种写法完全不符合HttpListener的设计使用规范,所有请求都会被异常中断,根本无法返回正常响应。
正确实现方式
Start()本身只需要在进入消息循环前调用一次即可,不需要反复启停,核心是要正确释放每个请求对应的资源:
var listener = new HttpListener(); listener.Prefixes.Add("http://*:8000/"); listener.Start(); // 仅启动一次监听器 while (true) { var context = listener.GetContext(); // 通过using块自动释放响应资源,避免连接泄漏 using (var response = context.Response) { // 此处编写业务响应逻辑 byte[] output = Encoding.UTF8.GetBytes("success"); response.ContentLength64 = output.Length; response.OutputStream.Write(output, 0, output.Length); } // 代码块执行结束后会自动关闭响应、释放TCP连接 }
内容的提问来源于stack exchange,提问作者Zvi Vered
相关产品推荐
相关产品推荐

