【问题标题】:For a client server program, what is the best approach to receive multiple client connection requests in parallel?对于客户端服务器程序,并行接收多个客户端连接请求的最佳方法是什么?
【发布时间】:2013-01-17 01:17:11
【问题描述】:

该程序是在 Linux 上用 C 语言开发的客户端服务器套接字应用程序。有一个远程服务器,每个客户端都连接到该服务器并将自己记录为在线。在任何给定时间点,很可能会有多个客户端在线,所有客户端都试图连接到服务器以将自己记录为在线/忙碌/空闲等。那么服务器如何处理这些并发请求。什么是好的设计方法(可能为每个连接请求分叉/多线程?)?

【问题讨论】:

    标签: c++ c linux sockets client-server


    【解决方案1】:

    一般来说,您需要一个线程池来服务请求。

    一个典型的结构会从一个线程开始,除了排队传入的请求之外什么都不做。由于它做的不多,一个线程通常很容易跟上网络的最大速度。

    这会将项目放入某种并发队列中。然后你有一个其他线程池从队列中读取项目,做需要的事情,然后将结果存放到另一个队列中(并重复,直到服务器关闭)。

    最后,您有另一个单线程,它只从结果队列中获取项目,并将回复发送给客户端。

    【讨论】:

      【解决方案2】:

      我个人会对服务器使用事件驱动的方法。在那里你注册一个回调,一旦连接到达就会被调用。以及每当套接字准备好读取或写入时的事件回调。

      与线程相比,拥有大量连接,您将获得巨大的性能和资源优势。但我也更喜欢这样的连接数。

      如果您确实需要使用多个内核,或者如果您有一些请求可能需要更长的时间来处理并且在没有线程的情况下处理它太复杂,我只会使用线程。

      我使用libev 作为基础库来处理事件驱动的网络。

      【讨论】:

      • 通过这种(简单)方法,Redis 在单个工作线程中达到每秒约 60.000 个事务(禁用日志记录)。而且由于只有一个工作线程,所以不存在多线程问题。
      【解决方案3】:

      最好的方法是结合事件驱动模型和多线程模型。

      您创建了一堆非阻塞套接字,但线程数应该少得多。 IE。每个线程 10 个套接字。

      然后您只需以非阻塞模式在每个线程上侦听一个事件(传入请求)并在它发生时对其进行处理。

      这种技术通常比单独的非阻塞套接字或多线程模型执行得更好。

      【讨论】:

        【解决方案4】:

        看看 Comer 的“Internetworking with TCP/IP”第 3 卷(BSD 套接字版本),它有详细的示例,用于编写服务器和客户端的不同方式。完整的代码(不幸的是没有解释)在网上。或者在http://tldp.org 中翻找,你会找到一系列教程。

        【讨论】:

          【解决方案5】:

          选择或投票或epoll

          这些是 *nix 系统上的工具,用于将多个事件源(连接)聚合到单个等待点。服务器将连接添加到数据结构中,然后通过调用 select 等来等待。当这些连接中的任何一个发生问题时,它会被唤醒,找出哪个连接,处理它,然后重新进入睡眠状态。详情见手册。

          在这些机制之上构建了几个更高级别的库,这使得它们的编程更加容易,例如libevent、libev 等。

          【讨论】:

            猜你喜欢
            • 2021-12-04
            • 1970-01-01
            • 2010-12-29
            • 1970-01-01
            • 2012-06-15
            • 2016-07-06
            • 2019-08-07
            • 1970-01-01
            • 2019-03-17
            相关资源
            最近更新 更多