如何用SuperSimpleTcp实现单客户端单连接(重复连接断旧连接)
如何在SuperSimpleTcp服务器中限制每个客户端仅保留一个连接
问题描述
当前使用SuperSimpleTcp库实现TCP服务器,希望限制同一客户端(按IP地址识别)仅能保持一个连接:当同一IP的客户端重新连接时,自动断开该IP的上一个连接,仅保留最新连接。同时寻求配置灵活的简易TCP库推荐。
现有代码
using SuperSimpleTcp; using System.Text; void Main(string[] args) { // instantiate SimpleTcpServer server = new SimpleTcpServer("127.0.0.1:9000"); // set events server.Events.ClientConnected += ClientConnected; server.Events.ClientDisconnected += ClientDisconnected; server.Events.DataReceived += DataReceived; // let's go! server.Start(); // once a client has connected... server.Send("[ClientIp:Port]", "Hello, world!"); Console.ReadKey(); } static void ClientConnected(object sender, ConnectionEventArgs e) { Console.WriteLine($"[{e.IpPort}] client connected"); } static void ClientDisconnected(object sender, ConnectionEventArgs e) { Console.WriteLine($"[{e.IpPort}] client disconnected: {e.Reason}"); } static void DataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine($"[{e.IpPort}]: {Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count)}"); }
解决方案
要实现单IP单连接的限制,核心是维护一个客户端IP与连接端口的映射,并在新连接建立时检查、清理旧连接:
- 使用线程安全字典存储IP到客户端
IpPort的映射(SuperSimpleTcp的事件回调在不同线程触发,必须保证线程安全) - 在
ClientConnected事件中,解析客户端IP,检查是否已有该IP的连接:- 若存在旧连接,调用
server.Disconnect()主动断开 - 更新字典,移除旧记录并添加新的连接信息
- 若存在旧连接,调用
- 在
ClientDisconnected事件中,从字典移除对应记录,避免内存泄漏
修改后的完整代码:
using SuperSimpleTcp; using System.Collections.Concurrent; using System.Text; // 线程安全字典:Key=客户端IP,Value=客户端连接的IpPort(格式如127.0.0.1:54321) private static readonly ConcurrentDictionary<string, string> _clientConnections = new ConcurrentDictionary<string, string>(); void Main(string[] args) { SimpleTcpServer server = new SimpleTcpServer("127.0.0.1:9000"); server.Events.ClientConnected += ClientConnected; server.Events.ClientDisconnected += ClientDisconnected; server.Events.DataReceived += DataReceived; server.Start(); Console.WriteLine("Server started, waiting for connections..."); Console.ReadKey(); } static void ClientConnected(object sender, ConnectionEventArgs e) { var server = (SimpleTcpServer)sender; // 从IpPort中拆分出客户端IP(忽略端口,同一客户端重连会使用不同端口) string clientIp = e.IpPort.Split(':')[0]; // 检查该IP是否已有活跃连接 if (_clientConnections.TryGetValue(clientIp, out string oldConnectionIpPort)) { Console.WriteLine($"[{clientIp}] already has a connection: {oldConnectionIpPort}, disconnecting old connection"); // 断开旧连接 server.Disconnect(oldConnectionIpPort); // 移除旧记录 _clientConnections.TryRemove(clientIp, out _); } // 添加新连接记录 _clientConnections.TryAdd(clientIp, e.IpPort); Console.WriteLine($"[{e.IpPort}] client connected"); } static void ClientDisconnected(object sender, ConnectionEventArgs e) { string clientIp = e.IpPort.Split(':')[0]; // 从字典中移除该IP的记录 _clientConnections.TryRemove(clientIp, out _); Console.WriteLine($"[{e.IpPort}] client disconnected: {e.Reason}"); } static void DataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine($"[{e.IpPort}]: {Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count)}"); }
说明
- 这里按客户端IP识别同一客户端,如果需要更严格的身份验证(比如自定义客户端ID),可以在客户端连接后发送身份标识,再基于标识维护连接映射
ConcurrentDictionary保证多线程下的安全操作,避免并发冲突
推荐TCP库
如果需要更灵活的配置选项,可考虑以下轻量TCP库:
- NetCoreServer:跨平台轻量TCP/UDP/HTTP服务器客户端库,支持自定义连接管理、SSL/TLS、心跳检测等,配置灵活且性能优异
- DotNetty:基于Java Netty的.NET实现,功能强大,适合构建高性能、可扩展的网络应用,支持多种协议,适配复杂场景
- Socket.IO Client .NET:如果需要WebSocket+TCP的混合支持,或者需要内置房间、广播等高级功能,该库是合适的选择
内容的提问来源于stack exchange,提问作者aygün bayır
相关产品推荐
相关产品推荐

