如果我在套接字上快速连续写入几次(使用 POSIX 函数write
),通常我写入的所有数据都会在单个 TCP 数据包中发送。除非我写得太多或者除非我在写之间等待太久。
内核是否缓冲我在套接字上写入的数据并定期发送数据包?或者 libc 处理这个问题吗?内核在发送数据包之前等待多长时间?我可以请求立即发送几乎空的数据包吗? UDP 或其他协议的处理方式是否不同?
我很想了解这一切是如何工作的,但我很难找到有关该主题的信息。
答案1
您的操作系统可能会在发送之前进行一些短期缓冲。例如 Linux 手册页tcp(7)
提到TCP_NODELAY
禁用该选项的选项(另请参阅setsockopt(2)
):
TCP_NODELAY
如果设置,则禁用 Nagle 算法。这意味着即使只有少量数据,数据段也总是尽快发送。不设置时,数据会被缓冲,直到有足够的量发送出去,从而避免频繁发送小数据包,导致网络利用率低下。该选项被TCP_CORK
;覆盖但是,设置此选项会强制显式刷新挂起的输出,即使TCP_CORK
当前已设置。
内格尔算法是实际的缓冲算法。如果我正确地遵循面包屑,RFC 1122似乎是它当前有效的定义。
这是内核,不是 libc。 C 库对 stdio 流进行缓冲 ( FILE *
),但write()
直接send()
进入内核。
对于 UDP,数据报的大小非常重要并且对上层可见,因此类似的损坏在那里是不可能的。