如何使用TcpListener监听多个TCP端口并处理多连接?
实现多端口监听与多连接处理的TCP服务器
你的问题核心在于只初始化了一个TcpListener实例,所以只能监听单个端口。要实现多端口监听,我们需要为每个目标端口创建独立的TcpListener,并让它们同时异步运行监听逻辑;同时,每个连接的处理也要异步化,确保多个连接可以并行处理。
下面是改造后的完整实现思路和代码示例:
步骤说明
- 从配置中读取多个端口(比如用逗号分隔的字符串)
- 为每个端口创建独立的
TcpListener实例 - 启动所有Listener的异步监听任务,让它们同时运行
- 每个Listener在接受连接后,将连接交给单独的异步方法处理,避免阻塞后续连接的接受
完整代码示例
private static async Task TcpServerAsync() { try { // 从配置读取IP地址 if (!IPAddress.TryParse(ConfigurationManager.AppSettings["ip"], out IPAddress ip)) { Console.WriteLine("无效的IP地址配置"); return; } // 从配置读取多个端口(示例格式:"8080,8081,8082") string portsConfig = ConfigurationManager.AppSettings["ports"]; if (string.IsNullOrEmpty(portsConfig)) { Console.WriteLine("未配置监听端口"); return; } var ports = portsConfig.Split(',') .Select(p => int.TryParse(p.Trim(), out int port) ? port : -1) .Where(p => p > 0 && p <= 65535) .ToList(); if (!ports.Any()) { Console.WriteLine("没有有效的监听端口"); return; } // 为每个端口创建监听任务 var listenerTasks = new List<Task>(); foreach (var port in ports) { listenerTasks.Add(StartPortListenerAsync(ip, port)); } // 等待所有监听任务完成(除非主动终止) await Task.WhenAll(listenerTasks); } catch (Exception ex) { Console.WriteLine($"服务器启动失败: {ex.Message}"); } } /// <summary> /// 启动单个端口的监听逻辑 /// </summary> private static async Task StartPortListenerAsync(IPAddress ip, int port) { TcpListener listener = null; try { listener = new TcpListener(ip, port); listener.Start(); Console.WriteLine($"已启动监听: {ip}:{port}"); // 循环接受该端口的连接 while (true) { // 异步等待客户端连接,不会阻塞线程 var client = await listener.AcceptTcpClientAsync(); Console.WriteLine($"新连接来自 {client.Client.RemoteEndPoint}(端口{port})"); // 将连接交给独立的异步方法处理,避免阻塞后续连接的接受 _ = HandleClientAsync(client, port); } } catch (Exception ex) { Console.WriteLine($"端口{port}监听出错: {ex.Message}"); } finally { listener?.Stop(); Console.WriteLine($"已停止监听: {ip}:{port}"); } } /// <summary> /// 处理单个客户端连接的逻辑 /// </summary> private static async Task HandleClientAsync(TcpClient client, int port) { using (client) using (var stream = client.GetStream()) { try { // 示例:读取客户端发送的数据 byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead); Console.WriteLine($"从端口{port}的客户端收到: {receivedData}"); // 示例:回复客户端 string response = $"已收到你的消息: {receivedData}"; byte[] responseBytes = Encoding.UTF8.GetBytes(response); await stream.WriteAsync(responseBytes, 0, responseBytes.Length); } } catch (Exception ex) { Console.WriteLine($"处理端口{port}的客户端连接时出错: {ex.Message}"); } finally { Console.WriteLine($"客户端 {client.Client.RemoteEndPoint}(端口{port})已断开连接"); } } }
关键要点解释
- 多端口监听:通过
StartPortListenerAsync为每个端口创建独立的监听循环,所有监听任务通过Task.WhenAll同时运行,互不干扰。 - 非阻塞连接处理:使用
await listener.AcceptTcpClientAsync()异步接受连接,不会阻塞线程;每个连接的处理通过_ = HandleClientAsync(...)启动独立的异步任务,确保同一端口可以同时处理多个连接。 - 资源管理:使用
using语句自动释放TcpClient和网络流,避免资源泄漏;每个Listener的finally块确保异常时能正确停止监听。 - 配置灵活性:通过配置文件的逗号分隔字符串定义多个端口,便于修改监听端口列表。
这样改造后,你的TCP服务器就能同时监听多个端口,并且每个端口都能并行处理多个客户端连接了。
内容的提问来源于stack exchange,提问作者mahboub_mo
相关产品推荐
相关产品推荐

