You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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与连接端口的映射,并在新连接建立时检查、清理旧连接:

  1. 使用线程安全字典存储IP到客户端IpPort的映射(SuperSimpleTcp的事件回调在不同线程触发,必须保证线程安全)
  2. 在ClientConnected事件中,解析客户端IP,检查是否已有该IP的连接:
    • 若存在旧连接,调用server.Disconnect()主动断开
    • 更新字典,移除旧记录并添加新的连接信息
  3. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:35:32