连接速度慢的客户端会破坏基于阻塞套接字的服务器吗?

Can clients with slow connection break down blocking-socket-based server?

根据阻塞套接字的定义,所有对 send() 或 recv() 的调用都是阻塞的,直到整个网络操作完成。这可能需要一些时间,尤其是在使用 tcp 并与连接速度较慢的客户端通信时。这当然是通过引入线程和线程池来解决的。但是如果所有线程都被一些慢客户端阻塞了会发生什么?例如,您的服务器想要为 10000 多个客户端提供服务,每秒有 100 个线程向所有用户发送数据。这意味着每个线程必须每秒调用 send() 100 次。如果在某个时候 100 个客户端连接速度太慢以至于对 send()/recv() 的一次调用需要 5 秒才能为他们完成(或者可能是故意这样做的攻击者),会发生什么情况。在这种情况下,所有 100 个线程都处于阻塞状态,其他人都在等待。这个一般是怎么解决的?向线程池添加更多线程可能不是解决方案,因为总是会有更慢的客户端,并且使用一些非常多的线程会在上下文切换资源消耗等方面引入更多问题。

Can clients with slow connection break down blocking-socket-based server?

是的,他们可以。而且它确实会消耗服务器端的资源。如果这种情况发生太多,您可能会以一种“拒绝服务”的形式结束。

请注意,如果您在服务器端使用阻塞 I/O,这是最糟糕的,因为您在发送响应时会占用一个线程。但是还是非阻塞的问题I/O。在后一种情况下,您使用服务器端套接字、端口号和内存来缓冲等待发送的响应。

如果你想保护你的服务器免受慢客户端的影响,它需要在发送响应时实现超时。如果服务器发现写入响应花费的时间太长......无论出于何种原因......它应该简单地关闭套接字。

典型的 Web 服务器默认执行此操作。

最后,正如 David 所说,使用非阻塞 I/O 将使您的服务器更具可扩展性。您可以用更少的资源处理更多的并发请求。但是单个服务器的扩展能力仍然有限。超过某个点后,您需要一种方法将请求负载分散到多个服务器上。