【问题标题】:what is the best way to handle new clients using select() in a server?在服务器中使用 select() 处理新客户端的最佳方法是什么?
【发布时间】:2011-10-23 03:42:40
【问题描述】:

我想用 C 语言编写一个异步套接字服务器,但在此之前我正在做一些研究。查看此处显示的 select() 套接字示例:http://www.gnu.org/s/hello/manual/libc/Server-Example.html#Server-Example 我可以看到示例程序每个选择循环只接受一个客户端(如果我没看错的话)。因此,如果有 20 个客户端和另外两个尝试连接,它会只接受第 21 个客户端然后处理另外 20 个(最坏的情况,假设所有 20 个其他客户端都需要读取)然后接受第 22 个?如果我在接受客户端后打破循环,以便它可以再次 select() 并在处理连接的客户端之前处理所有待处理的客户端,会更好吗?或者这是否违背了使用 select() 的目的?谢谢。

【问题讨论】:

    标签: c sockets select asynchronous


    【解决方案1】:

    您链接到的示例中显示的服务器模式很好;循环每次迭代只接受一个套接字并没有引入任何重大问题。

    要记住的关键点是,在精心设计的 select() 循环中,only 进程应该 ever 阻塞的地方是 select()称呼。特别是,如果编码正确,服务器将永远不会在 send()、recv() 或 accept() 中阻塞。最好将所有套接字设置为非阻塞模式(通过 fcntl(fd, F_SETFL, O_NONBLOCK))以保证这种行为。

    鉴于此,“在任何特定事件循环迭代中首先为哪些客户端提供服务”的精确顺序并不重要,因为所有客户端的套接字在它们准备好可供读取的数据(或缓冲区空间)后很快就会得到处理ready-for-write),并且所有新连接都会很快被接受。

    【讨论】:

    • 当然,您可以限制每次迭代中发送/接收的数据量,以避免长请求延迟较短的请求。我认为 Zeus Web 服务器在这些方面做了一些事情。您可能还应该为首先处理的请求添加一些随机性。
    • 谢谢,我认为我可以通过在接受客户端后中断来欺骗程序中的错误,但这实际上会降低性能。我想我不能走捷径。
    【解决方案2】:

    select() 让程序员决定如何处理通知。一次调用 select() 可以指示任何或所有套接字都有要读取的字节和要处理的一些连接请求。应用程序可以在调用 select() 之前处理所有通知,也可以在再次调用 select() 之前处理一个通知。

    【讨论】:

      【解决方案3】:

      可以在accept()之后在监听socket上使用poll()来查看是否还有更多的客户端等待连接。

      注意并发连接尝试的数量是由 backlog 参数来处理 listen(server_sock, backlog) - 在您引用的示例中,backlog 为 1。

      【讨论】:

        猜你喜欢
        • 2019-11-08
        • 2010-09-09
        • 2015-05-04
        • 1970-01-01
        • 1970-01-01
        • 2012-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多