C -在服务器中使用select()处理新客户端的最佳方式是什么?



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

您链接到的示例中显示的服务器模式是好的;循环每次迭代只接受一个套接字,这不会带来任何严重的问题。

要记住的关键一点是,在设计良好的select()循环中,放置进程应该块位于select()调用中。特别是,如果编码正确,服务器将永远不会在send()、recv()或accept()中阻塞。为了保证这种行为,最好将所有套接字设置为非阻塞模式(通过fcntl(fd, F_SETFL, O_NONBLOCK))。

考虑到这一点,"在任何特定的事件循环迭代中哪个客户端首先得到服务"的精确顺序并不重要,因为所有客户端的套接字在具有可读数据(或可写缓冲区空间)后很快得到处理,并且所有新连接都被快速接受。

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

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

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

最新更新