我不太清楚 TCP 和套接字的一些细节机制。
一个客户端通过 TCP 连接到服务器,并向服务器发送数据。如果发送速度远大于处理速度会怎样?比如客户端每秒发送1MiB,而服务器每秒只能处理1 KiB,会不会导致系统内存崩溃?
我知道套接字 API 中有接收缓冲区大小设置:
- 如果我设置了缓冲区大小但数据泛滥怎么办?
- 如果我不设置接收缓冲区大小怎么办?
我不太清楚 TCP 和套接字的一些细节机制。
一个客户端通过 TCP 连接到服务器,并向服务器发送数据。如果发送速度远大于处理速度会怎样?比如客户端每秒发送1MiB,而服务器每秒只能处理1 KiB,会不会导致系统内存崩溃?
我知道套接字 API 中有接收缓冲区大小设置:
总之当服务器每秒只能处理1k时,客户端将没有机会每秒发送1M。这有两个原因:
客户端发送超过广告窗口大小的数据是没有意义的,因为服务器首先会丢弃超出其窗口大小的任何段,因此如果客户端忽略窗口大小。
缓冲区位于不同的层中。您可以通过套接字选项设置的缓冲区是套接字级别的缓冲区,它们不能直接控制 TCP 窗口大小。如果您不设置这些缓冲区,则会在套接字级别获得默认缓冲区大小。TCP 排队取决于是否接收到窗口大小的乱序数据包。如果它接收到按顺序排列的数据,它会触发套接字级别,然后才将数据推入套接字级别缓冲区,然后仅针对可用空间的数量。如果 TCP 无法将它收到的所有数据推送到套接字缓冲区,那么这将对计算 TCP 窗口大小的算法产生影响。此计算机制基于 TCP 缓冲区中剩余的字节数。
没有人会崩溃,无论是服务器还是客户端。
在客户端,可以高速发送,类似的事情会发生,因为 TCP 会根据服务器的广告窗口大小看到它不能在线路上放置太多数据。所以客户端发送缓冲区将填满。如果它已满,客户端套接字将在发送中阻塞(阻塞模式)或返回一个错误指示它会阻塞(非阻塞模式)。
所以这不仅仅说明会发生什么,而且我还试图解释为什么会发生这些事情以及它是如何实现的。
如果发送速度远大于处理速度会怎样?例如,如果客户端每秒发送 1 MiB,但服务器每秒只能处理 1 KiB……</p>
如果发送方处于阻塞模式,如果它比接收方领先太多,它将阻塞。
如果它处于非阻塞模式,send()
将返回 -1errno == EAGAIN/EWOULDBLOCK.
会不会导致系统内存崩溃?
不。
我知道套接字 API 中有接收缓冲区大小设置:
- 如果我设置了缓冲区大小但数据泛滥怎么办?
当接收缓冲区已满时,接收主机会告诉发送方停止发送。
- 如果我不设置接收缓冲区大小怎么办?
您将获得默认尺寸。
网络层有拥塞控制算法来控制这些情况:-
在传输层(TCP),某些策略用于摆脱这种情况:-
综合以上几点,我希望您可能已经了解如果客户端试图淹没服务器会发生什么。
在以下情况下,根据上述因素进行调整/滑动窗口(在传输层)、抖动控制、减载(在网络层)等操作:
(i) 网络/路由器充斥着请求,或者,(ii) 传输层 (TCP) 的两个进程之间的数据流是不规则和错误的。