简体   繁体   English

什么时候需要修改socket的接收缓冲区大小?

[英]When do you need to modify the receive buffer size of sockets?

From time to time I see network related code in legacy source code and elsewhere modifying the receive buffer size for sockets (using setsockopt with the SO_RCVBUF option).我不时在遗留源代码和其他地方看到网络相关代码修改套接字的接收缓冲区大小(使用带有SO_RCVBUF选项的setsockopt )。 On my Windows 10 system the default buffer size for sockets seems to be 64kB.在我的 Windows 10 系统上,套接字的默认缓冲区大小似乎是 64kB。 The legacy code I am working on now (written 10+ years ago) sets the receive buffer size to 256kB for each socket.我现在正在处理的遗留代码(10 多年前编写)将每个套接字的接收缓冲区大小设置为 256kB。

Some questions related to this:与此相关的一些问题:

  1. Is there any reason at all to modify receive buffer sizes when sockets are monitored and read continuously, eg using select ?当套接字被连续监视和读取时,是否有任何理由修改接收缓冲区大小,例如使用select
  2. If not, was there some motivation for this 10+ years ago?如果没有,10 多年前是否有这样做的动机?
  3. Are there any examples, use cases or applications, where modification of receive buffer sizes (or even send buffer sizes) for sockets are needed?是否有任何示例、用例或应用程序需要修改套接字的接收缓冲区大小(甚至发送缓冲区大小)?

Typically receive-buffer sizes are modified to be larger because the code's author is trying to reduce the likelihood of the condition where the socket's receive-buffer becomes full and therefore the OS has to drop some incoming packets because it has no place to put the data.通常接收缓冲区的大小被修改为更大,因为代码的作者试图减少套接字的接收缓冲区变满的情况的可能性,因此操作系统必须丢弃一些传入的数据包,因为它没有地方放置数据. In a TCP-based application, that condition will cause the stream to temporarily stall until the dropped packets are successfully resent;在基于 TCP 的应用程序中,这种情况将导致流暂时停止,直到成功重新发送丢弃的数据包; in a UDP-based application, that condition will cause incoming UDP packets to be silently dropped.在基于 UDP 的应用程序中,这种情况将导致传入的 UDP 数据包被静默丢弃。

Whether or not doing that is necessary depends on two factors: how quickly data is expected to fill up the socket's receive-buffer, and how quickly the application can drain the socket's receive-buffer via calls to recv() .这样做是否必要取决于两个因素:预计数据填充套接字接收缓冲区的速度,以及应用程序通过调用recv()耗尽套接字接收缓冲区的速度。 If the application is reliably able to drain the buffer faster than the data is received, then the default buffer size is fine;如果应用程序能够可靠地以比接收数据更快的速度排空缓冲区,那么默认缓冲区大小就可以了; OTOH if you see that it is not always able to do so, then a larger receive-buffer-size may help it handle sudden bursts of incoming data more gracefully. OTOH 如果您发现它并不总是能够这样做,那么更大的接收缓冲区大小可能会帮助它更优雅地处理突然的传入数据。

Is there any reason at all to modify receive buffer sizes when sockets are monitored and read continuously, eg using select?当套接字被连续监视和读取时,是否有任何理由修改接收缓冲区大小,例如使用选择?

There could be, if the incoming data rate is high (eg megabytes per second, or even just occasional bursts of data at that rate), or if the thread is doing something between select()/recv() calls that might keep it busy for a significant period of time -- eg if the thread ever needs to write to disk, disk-write calls might take several hundred milliseconds in some cases, potentially allowing the socket's receive buffer to fill during that period.如果传入的数据速率很高(例如每秒兆字节,甚至只是偶尔以该速率突发数据),或者线程在 select()/recv() 调用之间执行某些操作可能会使其忙碌,则可能会出现这种情况在相当长的一段时间内——例如,如果线程需要写入磁盘,在某些情况下,磁盘写入调用可能需要数百毫秒,在此期间可能会填满套接字的接收缓冲区。

For very high-bandwidth applications, even a very short pause (eg due to the thread being kicked off of the CPU for a few quanta, so that another thread can run for a quantum or two) might be enough to allow the buffer to fill up.对于非常高带宽的应用程序,即使是非常短的暂停(例如,由于线程被踢出 CPU 几个量程,以便另一个线程可以运行一两个量程)可能足以让缓冲区填满向上。 It depends a lot on the application's use-case, and of course on the speed of the CPU hardware relative to the network.这在很大程度上取决于应用程序的用例,当然还取决于 CPU 硬件相对于网络的速度。

As for when to start messing with receive-buffer-sizes: don't do it unless you notice that your application is dropping enough incoming packets that it is noticeably limiting your app's network performance.至于何时开始处理接收缓冲区大小:不要这样做,除非您注意到您的应用程序丢弃了足够多的传入数据包,从而明显限制了您的应用程序的网络性能。 There's no sense allocating more RAM than you need to.分配比您需要的更多的 RAM 是没有意义的。

For TCP, the RECVBUF buffer is the maximum number of unread bytes that the kernel can hold.对于 TCP,RECVBUF 缓冲区是内核可以容纳的最大未读字节数。 In TCP the window size reflects the maximum number of unacknowledged bytes the sender can safely send.在 TCP 中,窗口大小反映了发送方可以安全发送的最大未确认字节数。 The sender will receive an ACK which will include a new window which depends on the free space in the RECVBUF.发送方将收到一个 ACK​​,其中将包含一个新窗口,该窗口取决于 RECVBUF 中的可用空间。

When RECVBUF is full the sender will stop sending data.当 RECVBUF 已满时,发送方将停止发送数据。 Since mechanism means the sender will not be able to send more data than the receiving application can receive.由于机制意味着发送方将无法发送比接收应用程序可以接收的更多的数据。

A small RECVBUF will work well on low latency networks but on high bandwidth high latency networks ACKS may take too long to get to the sender and since the sender has run out of window, the sender will not make use of the full bandwidth.小的 RECVBUF 将在低延迟网络上运行良好,但在高带宽高延迟网络上,ACKS 可能需要很长时间才能到达发送方,并且由于发送方已用完窗口,发送方将无法使用全部带宽。

Increasing the RECVBUF size increases the window which means the sender can send more data while waiting for an ACK, this then will allow the sender to make use of the entire bandwidth.增加 RECVBUF 大小会增加窗口,这意味着发送方可以在等待 ACK 时发送更多数据,这将允许发送方利用整个带宽。 It does mean that things are less responsive.这确实意味着事情的响应性较差。

Shrinking the RECVBUF means the sender is more responsive and aware of the receiver not eating the data and can back off a lot quicker.缩小 RECVBUF 意味着发送方响应更快,并意识到接收方没有吃数据,并且可以更快地退出。

The same logic applies for the SENDBUF as well.同样的逻辑也适用于 SENDBUF。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM