【问题标题】:When do you need to modify the receive buffer size of sockets?什么时候需要修改套接字的接收缓冲区大小?
【发布时间】:2020-03-31 14:49:46
【问题描述】:

我不时在遗留源代码和其他地方看到网络相关代码修改套接字的接收缓冲区大小(使用 setsockoptSO_RCVBUF 选项)。在我的 Windows 10 系统上,套接字的默认缓冲区大小似乎是 64kB。我现在正在处理的遗留代码(写于 10 多年前)将每个套接字的接收缓冲区大小设置为 256kB。

与此相关的一些问题:

  1. 当套接字被监视和连续读取时,是否有任何理由修改接收缓冲区大小,例如使用select?
  2. 如果不是,那么 10 多年前是否有这样做的动机?
  3. 是否有任何示例、用例或应用程序需要修改套接字的接收缓冲区大小(甚至发送缓冲区大小)?

【问题讨论】:

  • 这能回答你的问题吗? What are SO_SNDBUF and SO_RECVBUF 即它是特定于应用程序的 - 如果缓冲区在被读取之前已填满,则发送方将被告知减慢 TCP/IP 或丢弃 UDP 的数据包。所以这取决于应用程序的处理方式。
  • 可能部分,但不完全。我知道缓冲区是什么以及它们是如何工作的。我的问题更多是关于何时在实践中使用它们。
  • 我们需要更多的上下文来回答这个问题。数据包是否以突发形式到达?它们是如何处理的,可以中断等吗?对于 SO 类型的问答,这可能太多了。
  • 在我的具体示例中,网络流量负载从低到中等,传入数据在其自己的线程中连续处理。不过,我的问题旨在更笼统。但也许很难说一些笼统的东西。

标签: c++ sockets networking


【解决方案1】:

通常将接收缓冲区的大小修改为更大,因为代码作者试图降低套接字接收缓冲区已满的情况的可能性,因此操作系统必须丢弃一些传入的数据包,因为它没有地方可以把数据。在基于 TCP 的应用程序中,这种情况会导致流暂时停止,直到成功重新发送丢弃的数据包;在基于 UDP 的应用程序中,这种情况会导致传入的 UDP 数据包被静默丢弃。

是否有必要这样做取决于两个因素:预计数据填满套接字接收缓冲区的速度,以及应用程序通过调用recv() 耗尽套接字接收缓冲区的速度。如果应用程序能够可靠地比接收数据更快地耗尽缓冲区,那么默认缓冲区大小就可以了; OTOH,如果您发现它并不总是能够这样做,那么更大的接收缓冲区大小可能有助于它更优雅地处理突然爆发的传入数据。

有什么理由在套接字时修改接收缓冲区大小 持续监控和读取,例如使用选择?

如果传入的数据速率很高(例如每秒兆字节,甚至只是偶尔以该速率突发的数据),或者如果线程在 select()/recv() 调用之间做一些可能让它忙碌很长一段时间——例如如果线程需要写入磁盘,在某些情况下磁盘写入调用可能需要几百毫秒,这可能会导致套接字的接收缓冲区在此期间被填满。

对于非常高带宽的应用程序,即使是非常短的暂停(例如,由于线程在 CPU 上被踢出几个 quanta,以便另一个线程可以运行一个或两个 quanta)可能就足以让缓冲区填满。这在很大程度上取决于应用程序的用例,当然还取决于 CPU 硬件相对于网络的速度。

至于什么时候开始搞乱接收缓冲区大小:除非您注意到您的应用程序丢弃了足够多的传入数据包,从而明显限制了您的应用程序的网络性能,否则请不要这样做。分配比您需要的更多的 RAM 是没有意义的。

【讨论】:

  • 在 TCP 数据速率由 TCP 窗口管理。端点不需要删除任何数据。不过,数据可能会在途中被路由器丢弃。
  • @doron 数据不会被丢弃,但 packets 可以;应用程序可见的程序员后果将是 TCP 数据传输将比其他情况下更慢。
  • 只有在数据包不可路由的情况下,才会被 IP 层丢弃数据。
【解决方案2】:

对于 TCP,RECVBUF 缓冲区是内核可以容纳的最大未读字节数。在 TCP 中,窗口大小反映了发送方可以安全发送的未确认字节的最大数量。发送方将收到一个 ACK​​,其中将包含一个新窗口,该窗口取决于 RECVBUF 中的可用空间。

当 RECVBUF 已满时,发送方将停止发送数据。由于机制意味着发送方将无法发送比接收应用程序接收更多的数据。

一个小的 RECVBUF 在低延迟网络上运行良好,但在高带宽高延迟网络上,ACKS 可能需要很长时间才能到达发送方,并且由于发送方已超出窗口,发送方将无法使用全部带宽.

增加 RECVBUF 大小会增加窗口,这意味着发送方可以在等待 ACK 时发送更多数据,这将允许发送方利用整个带宽。这确实意味着事情的响应速度较慢。

缩小 RECVBUF 意味着发送方反应更快,并且知道接收方没有吃掉数据,并且可以更快地回退。

同样的逻辑也适用于 SENDBUF。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    相关资源
    最近更新 更多