套接字recv()强制刷新套接字send()缓冲区吗?

时间:2013-10-29 18:37:27

标签: sockets tcp

在我的应用程序中,我向服务器发送了两条小消息(类似于memcached的服务)。在类似Python的伪代码中,这看起来像:

sock.send("add some-key 0")
ignored = sock.recv(...)
sock.send("incr some-key 1")
new_value = sock.recv(...)

由于服务器支持fire-and-forget-style写入,我可以优化此代码看起来更像:

sock.send("add some-key 0 noreply")
sock.send("incr some-key 1")
new_value = sock.recv(...)

然而,这需要更长的时间 - 这个版本的平均时间为40毫秒,而前者平均不到1毫秒。

此外,我注意到如果我使用TCP_NODELAY创建套接字,从而禁用Nagle的算法,则第二个代码段的时序与第一个类似。这表明延迟发生在两个send()之间(“写 - 写 - 读”问题)。

我有理由相信,禁用Nagle是我的应用程序的正确举措 - 我有相当大的相当小的写入量,必须以尽可能小的延迟处理 - 但我不知道为什么它在第一个例子中没有必要。 recv()强制内核发送任何缓冲写入吗?我怀疑这是真的,但我无法在任何地方找到相应的文档。

(注意这是Linux 2.6.32和带有Python 2.6.8的glibc 2.12,如果其中任何一个与答案有关)

1 个答案:

答案 0 :(得分:1)

  

recv()强制内核发送任何缓冲的写入吗?

没有。 TCP连接的两个方向完全独立。

Nagle算法在某些情况下延迟发送数据包最多200毫秒,以便它可以与后续写入合并。这就是你所看到的,当你禁用Nagle时它就会停止发生。

  

我怀疑这是真的

不是。

  

但我无法在任何地方找到相应的文档。

你不会。