3

我不太清楚 TCP 和套接字的一些细节机制。

一个客户端通过 TCP 连接到服务器,并向服务器发送数据。如果发送速度远大于处理速度会怎样?比如客户端每秒发送1MiB,而服务器每秒只能处理1 KiB,会不会导致系统内存崩溃?

我知道套接字 API 中有接收缓冲区大小设置:

  1. 如果我设置了缓冲区大小但数据泛滥怎么办?
  2. 如果我不设置接收缓冲区大小怎么办?
4

3 回答 3

6

总之当服务器每秒只能处理1k时,客户端将没有机会每秒发送1M。这有两个原因:

  • TCP有慢启动机制
  • TCP 有一个窗口机制,TCP 连接的每一端都在不断地向另一端通告自己的接收能力。

客户端发送超过广告窗口大小的数据是没有意义的,因为服务器首先会丢弃超出其窗口大小的任何段,因此如果客户端忽略窗口大小。

缓冲区位于不同的层中。您可以通过套接字选项设置的缓冲区是套接字级别的缓冲区,它们不能直接控制 TCP 窗口大小。如果您不设置这些缓冲区,则会在套接字级别获得默认缓冲区大小。TCP 排队取决于是否接收到窗口大小的乱序数据包。如果它接收到按顺序排列的数据,它会触发套接字级别,然后才将数据推入套接字级别缓冲区,然后仅针对可用空间的数量。如果 TCP 无法将它收到的所有数据推送到套接字缓冲区,那么这将对计算 TCP 窗口大小的算法产生影响。此计算机制基于 TCP 缓冲区中剩余的字节数。

没有人会崩溃,无论是服务器还是客户端。

在客户端,可以高速发送,类似的事情会发生,因为 TCP 会根据服务器的广告窗口大小看到它不能在线路上放置太多数据。所以客户端发送缓冲区将填满。如果它已满,客户端套接字将在发送中阻塞(阻塞模式)或返回一个错误指示它会阻塞(非阻塞模式)。

所以这不仅仅说明会发生什么,而且我还试图解释为什么会发生这些事情以及它是如何实现的。

于 2015-05-24T14:29:28.563 回答
2

如果发送速度远大于处理速度会怎样?例如,如果客户端每秒发送 1 MiB,但服务器每秒只能处理 1 KiB……</p>

如果发送方处于阻塞模式,如果它比接收方领先太多,它将阻塞。

如果它处于非阻塞模式,send()将返回 -1errno == EAGAIN/EWOULDBLOCK.

会不会导致系统内存崩溃?

不。

我知道套接字 API 中有接收缓冲区大小设置:

  1. 如果我设置了缓冲区大小但数据泛滥怎么办?

当接收缓冲区已满时,接收主机会告诉发送方停止发送。

  1. 如果我不设置接收缓冲区大小怎么办?

您将获得默认尺寸。

于 2015-05-24T08:18:52.197 回答
-1

网络层有拥塞控制算法来控制这些情况:-

  1. 数据包排队和服务策略
  2. 包丢弃策略等

在传输层(TCP),某些策略用于摆脱这种情况:-

  1. 重传策略
  2. 流量控制策略(在这里您将了解TCP 中的滑动窗口协议来控制数据流
  3. 超时判定等

综合以上几点,我希望您可能已经了解如果客户端试图淹没服务器会发生什么。

在以下情况下,根据上述因素进行调整/滑动窗口(在传输层)、抖动控制、减载(在网络层)等操作:

(i) 网络/路由器充斥着请求,或者,(ii) 传输层 (TCP) 的两个进程之间的数据流是不规则和错误的。

于 2015-05-24T06:58:21.360 回答