【问题标题】:Designing a multi-client tcp server to process data设计一个多客户端 tcp 服务器来处理数据
【发布时间】:2013-11-04 03:37:36
【问题描述】:

我正在尝试重写我当前的项目以包含更多功能和稳定性,并且需要一些帮助来设计它。这是它的主要内容(适用于 linux):

  • TCP_SERVER 接收连接(验证数据包)
  • TCP_SERVER 启动一个新的(线程/分叉)来处理新客户端
  • TCP_SERVER 将从客户端接收许多数据包 > 将添加到循环缓冲区中
  • 将为该客户端创建一个单独的线程来处理这些数据包并构建对象列表
  • 应创建另一个线程以将部分对象列表发送到另一个客户端

将所有处理分成线程的原因是因为服务器会收到很多数据包并且处理将无法跟上(这需要快速,因为它的时间敏感)(我不确定 tcp 是否会丢弃数据包如果内部缓冲区变得太大?),另一个线程发送到另一个客户端以尽可能保持处理速度。

所以对于每个新连接,应该创建 3 个线程。 1 接收数据包,1 处理它们,1 将处理后的数据发送到另一个客户端(从技术上讲,这是同一个人/IP,只是在不同的设备上)

我需要帮助设计这个,如何构建这个,使用什么(forks/threads),使用什么库。

【问题讨论】:

    标签: c++ multithreading sockets networking tcp


    【解决方案1】:

    试图自己做这件事会给你带来痛苦的世界。专注于您的实际应用程序,并利用现有的套接字处理框架。比如你说:

    对于每个新连接,应创建 3 个线程

    该声明表示以下内容: 1. 您以前没有大规模地这样做过,也没有意识到所有这些线程将产生的影响。 2. 您从未对线程创建或同步操作进行基准测试。 3. 这种方法可能出错的事情非常多。

    认真考虑使用可以为您完成大部分工作的现有库。在这个问题上搭建好脚手架实际上可能需要数年时间,而且你最好专注于你的代码,而不是所有的随机管道。

    Boost C++ libraries 似乎有一个不错的异步 C++ 套接字处理基础设施。将它与一些现有的 C++ 线程池结合起来,您可能会很快拥有一个高性能的解决方案。

    我也会质疑您为此使用 C++。 Java 和 C# 都很好地完成了高度可扩展的套接字服务器,并且一些高级语言工具(Spring、Guarva 等)可能非常非常有价值。如果您想通过 TLS 或其他机制保护这一点,您可能还会发现在 Java 或 C# 中比在 C++ 中更容易。

    您会关心的一些主要事项: 1. 真正的异步 I/O 将在性能和可扩展性方面取得巨大的胜利。努力做到这一点。 boost asio library 看起来不错。 2. 专注于你的特性和稳定性,而不是构建一个新的套接字处理平台。 3. 线程很昂贵,避免创建它们。线程池是你的朋友。

    【讨论】:

    • 是的,我一直在研究 boost,这似乎让这变得容易多了。但是我将如何设计它,以便每个连接的客户端都有自己的(对象列表/向量列表)。它几乎就像一个游戏服务器,每个玩家都有自己的世界观,并根据他们的输入/数据包获取他们的实体列表版本。
    • 几乎所有花哨的套接字服务器都是这样工作的。当异步接收线程说“我有足够的数据来处理”时,它会将该数据发布到线程池中的工作线程。工作线程唤醒,在正确的数据中分页(通过 DB 命中或其他方式),处理数据,然后将其发送到不同的套接字上。真的没有别的办法了。如果您的数据在“内存中”,那么您就有了某种标记。当“Remote socket 1234”发送了足够的数据时,你从你的静态哈希表中读取数据并对用户的数据进行操作。
    【解决方案2】:

    您计划为服务器处理的每个连接创建一个或多个线程。线程不是空闲的,它们会带来内存和 CPU 开销,当您有许多活动线程时,您也会开始争用资源。

    您预期的使用模式是什么?您是否期望当您有 8 个连接时,所有 8 个网络线程将消耗 100% 的 cpu 核心推/拉数据包?还是您希望他们的周转率相对较低?

    随着您添加更多线程,您将开始不得不花费更多时间来争夺互斥锁等资源。

    一种更好的模式是为网络 io 设置一个或多个线程 - 大多数操作系统都有“告诉我这些网络连接中的一个或多个何时具有 io”的机制,这比拥有大量单独的线程更有效只为一个连接做同样的事情。

    然后对于实际处理,启动一个工作线程池来执行实际工作,从而最大限度地减少对资源的竞争。您可以监控工作量,以确定是否需要加快速度来满足交付要求。

    您可能还想研究一些东西来为您实施网络 IO 基础架构;我使用 libevent 获得了非常好的性能结果,但我只需要处理性能/可靠性非常高的网络系统。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-25
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      相关资源
      最近更新 更多