我必须监听传入客户端连接的端口,并为它们提供一些数据。要处理多个客户端连接,我需要循环中的 listen()
和 accept()
。
但是,我知道客户端连接将会很少。因此,在循环中连续运行 listen()
和 accept()
并没有多大意义 - 只是看起来很浪费。
我疯了还是有更好的方法来做到这一点。
我还在想,如果我 sleep()
我的线程运行 while 循环一秒钟,我仍然会占用 CPU 少很多(少 50% ?(因为循环是仅每隔一秒工作..))。但在这种情况下,如果客户端连接在线程休眠时进入,我会错过该连接吗?或者操作系统是否为我处理这个问题(即,它意识到该端口上触发了一个监听,并以某种方式对请求进行排队,以便监听稍后使用)?
最佳答案
与客户端连接充足时的监听方式相同。
您只需要listen()
一次——这会绑定(bind)套接字以接受连接。 accept()
将阻塞,直到在此套接字上收到连接。当它被阻塞时,它将等待操作系统指示新连接已进入;在此期间线程将处于休眠状态。
因此,在此模型中,您应该有一个或多个线程专门用于处理来自现有连接的请求,以及一个单独的线程,该线程将简单地 accept()
一个新套接字并将其添加到您的列表中打开的套接字。当该线程等待新连接时,它不会使用任何 CPU 时间,因此不会浪费。
(您还可以使用 epoll()
机制在单个线程上执行所有这些任务。在任何一种情况下,等待新连接进入的行为都不会消耗 CPU 时间.)
要回答您的问题,如果您没有在 accept()
中被阻止并且有新连接进入,会发生什么情况:是的,操作系统维护一个传入连接队列。每次调用 accept()
都会返回队列中的第一个此类连接。 (如果此时队列中没有任何内容,那么它将阻塞,直到有新连接为止。)
关于c++ - 当客户端连接很少且间隔很远时,服务器监听的明智方法是什么(在Linux上使用套接字编程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25347917/