C#程序处理单次HTTP请求后停止,如何实现持续运行?
修改代码以支持持续运行并处理多次请求
你的程序当前只处理一次HTTP请求就停止,原因是Main方法在处理完第一个连接后就执行完毕,导致程序退出。要让程序持续运行并处理多次请求,需要做以下修改:
- 使用无限循环持续接受新连接:在
server.Start()后添加无限循环,不断调用server.AcceptSocket()等待新的客户端连接。 - 异步处理每个客户端连接:为每个新连接启动独立任务,避免阻塞主线程,支持并发处理多个请求。
- 添加异常处理:防止单个请求的错误导致整个服务器崩溃。
以下是修改后的完整代码:
using System; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading.Tasks; namespace Pretpark { class Program { static void Main(string[] args) { TcpListener server = new TcpListener(IPAddress.Loopback, 5000); server.Start(); Console.WriteLine("服务器已启动,监听端口5000..."); // 无限循环持续接受新连接 while (true) { Socket connectie = server.AcceptSocket(); // 异步处理客户端请求,不阻塞主线程 Task.Run(() => HandleClient(connectie)); } } // 单独方法处理每个客户端请求 private static void HandleClient(Socket connectie) { try { using (connectie) using Stream request = new NetworkStream(connectie); using StreamReader requestLezer = new StreamReader(request); string[]? regel1 = requestLezer.ReadLine()?.Split(" "); if (regel1 == null) return; (string methode, string url, string httpversie) = (regel1[0], regel1[1], regel1[2]); string? regel = requestLezer.ReadLine(); int contentLength = 0; while (!string.IsNullOrEmpty(regel) && !requestLezer.EndOfStream) { // 限制分割次数,避免Header值含冒号时出错 string[] stukjes = regel.Split(new[] { ':' }, 2); if (stukjes.Length == 2) { (string header, string waarde) = (stukjes[0].Trim(), stukjes[1].Trim()); if (header.ToLower() == "content-length") int.TryParse(waarde, out contentLength); // 避免解析失败崩溃 } regel = requestLezer.ReadLine(); } if (contentLength > 0) { char[] bytes = new char[contentLength]; requestLezer.Read(bytes, 0, contentLength); } // 返回响应 byte[] response = System.Text.Encoding.ASCII.GetBytes( "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 11\r\n\r\nHello World"); connectie.Send(response); } catch (Exception ex) { Console.WriteLine($"处理请求出错: {ex.Message}"); } } } }
关键修改说明:
- 无限循环:
while(true)让服务器持续监听新连接,不会在处理完一个请求后退出。 - 异步处理:
Task.Run将客户端逻辑放到后台任务,主线程可立即回到接受新连接状态,支持并发请求。 - 鲁棒性优化:
- 限制Header分割次数,避免值含冒号时出错。
- 用
int.TryParse替代int.Parse,防止Content-Length格式错误导致崩溃。 - 异常捕获确保单个请求的错误不会影响整个服务器。
- 代码简化:用
IPAddress.Loopback替代手动构造IP字节数组,代码更简洁。
内容的提问来源于stack exchange,提问作者Rav
相关产品推荐
相关产品推荐

