简体   繁体   English

Linux 上的 UDP 或 TCP 缓冲区大小应该有多大?

[英]How large should UDP or TCP buffer size be on Linux?

I need to write a couple of C++ applications on Linux, one to receive data via UDP and the second TCP.我需要在 Linux 上编写几个 C++ 应用程序,一个通过 UDP 和第二个 TCP 接收数据。

The only thing I'm unsure about is regarding the buffer.我唯一不确定的是关于缓冲区。

How do I choose what size buffer?我如何选择什么大小的缓冲区?

If I make the buffer large enough, am I guaranteed to avoid scenarios where half of a packet is at the end of my buffer and I need to copy the bytes to the beginning and then receive the remaining half of the packet?如果我使缓冲区足够大,我是否可以保证避免一半数据包位于缓冲区末尾并且我需要将字节复制到开头然后接收剩余一半数据包的情况?

I am going to use the Linux socket API functions if it matters.如果重要的话,我将使用 Linux 套接字 API 函数。

If I make the buffer large enough, am I guaranteed to avoid scenarios where half of a packet is at the end of my buffer and I need to copy the bytes to the beginning and then receive the remaining half of the packet?如果我使缓冲区足够大,我是否可以保证避免一半数据包位于缓冲区末尾并且我需要将字节复制到开头然后接收剩余一半数据包的情况?

Based on the above paragraph, I'm going to surmise that the buffer you are referring to is the application-space buffer that you pass into your recv() calls, and not the in-kernel buffer that the networking stack maintains on your application's behalf.根据上面的段落,我将推测您所指的缓冲区是您传递给recv()调用的应用程序空间缓冲区,而不是网络堆栈在您的应用程序上维护的内核缓冲区代表。

For UDP, the answer is simple: Your buffer needs to be large enough to hold the largest possible datagram you expect to receive.对于 UDP,答案很简单:您的缓冲区需要足够大,以容纳您希望接收的最大可能数据报。 Since UDP datagrams are typically less than 1500 bytes (to avoid fragmentation) and in all cases are <= 65507 bytes (since that is the maximum datagram size the UDP protocol supports), you can always make your receive buffer 65507 bytes long, or smaller if you want to save a bit on RAM usage.由于 UDP 数据报通常小于 1500 字节(以避免碎片)并且在所有情况下都 <= 65507 字节(因为这是 UDP 协议支持的最大数据报大小),您始终可以将接收缓冲区设置为 65507 字节或更小如果您想节省一点 RAM 使用量。

For TCP, the protocol is stream-based, so the amount of data written in to your recv-buffer by a given recv() call is unrelated to packet sizes.对于 TCP,该协议是基于流的,因此通过给定的recv()调用写入您的 recv 缓冲区的数据量与数据包大小无关。 Another consequence of TCP being stream-based is that it doesn't do any message-framing -- that means you will have to handle partial messages regardless of how big or small you make your buffer. TCP 基于流的另一个后果是它不进行任何消息帧化——这意味着无论缓冲区大小如何,您都必须处理部分消息。 The only advantage of a larger TCP buffer is that it's a bit more efficient to handle more bytes at a time instead of fewer, again at the cost of using a little more RAM.更大的 TCP 缓冲区的唯一优点是一次处理更多字节而不是更少字节更有效,同样以使用更多 RAM 为代价。

If I make the buffer large enough, am I guaranteed to avoid scenarios where half of a packet is at the end of my buffer and I need to copy the bytes to the beginning and then receive the remaining half of the packet?如果我使缓冲区足够大,我是否可以保证避免一半数据包位于缓冲区末尾并且我需要将字节复制到开头然后接收剩余一半数据包的情况?

For TCP: It doesn't matter.对于 TCP:没关系。 Packets are an implementation detail.数据包是一个实现细节。 The application doesn't even have to think about them.应用程序甚至不必考虑它们。 TCP is a byte-stream protocol and all you ever get from the API is a stream of bytes. TCP 是一种字节流协议,您从 API 中获得的只是一个字节流。 Message boundaries are never preserved.永远不会保留消息边界。

For UDP: Packets are still an implementation detail.对于 UDP:数据包仍然是一个实现细节。 You send and receive datagrams.您发送和接收数据报。 Your read function always gets an entire datagram so long as your buffer is as large as the largest datagram your application protocol supports.只要您的缓冲区与您的应用程序协议支持的最大数据报一样大,您的读取函数始终会获取整个数据报。

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

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