一个TCP连接的高Recv-Q的原因是什么?

5
在我的应用程序中,我发现TCP连接上的send()调用有时会被阻塞。每当发生这种情况时,从netstat输出中可以看到TCP连接的Recv-Q非常高:
tcp   314238      0 10.8.8.21:47302         10.8.8.11:5672          ESTABLISHED
tcp   313276      0 10.8.8.21:47294         10.8.8.11:5672          ESTABLISHED

是什么原因导致TCP连接的接收缓冲区被填满?这如何导致我的send()调用无限期地挂起?

p.s. 可能与此相关,此TCP连接是在我的应用程序和RabbitMQ服务器之间建立的。


当您的应用程序在一段时间内未从套接字读取数据时,接收缓冲区将填满。但这不应影响您端点的发送。您能否检查对面发生了什么?顺便说一下,这里有一些有用的提示和场景,其中Recv-Q和Send-Q具有非零值:https://dev59.com/MVoV5IYBdhLWcg3wRtAw - Oleg Kuralenko
当然会影响发送。TCP将关闭接收窗口,此时发送方必须停止发送。RFC 793。 - user207421
2个回答

3

什么原因会导致TCP连接的接收缓冲区被填满?

接收方接收速度慢于发送方发送速度。

这怎么会导致我的send()调用无限期挂起?

当接收缓冲区填满时,TCP关闭接收窗口,从而阻止发送方发送。发送方不能发送超过接收TCP在其接收窗口中广告的数据量。


-1
可能会导致TCP连接的接收缓冲区被填满?这会如何导致我的send()调用无限期地挂起?
假设您有相同的线程调用send()和recv(),当它在send()调用中被阻塞时,自然不会调用recv(),接收到的数据必须排队。因此,填充recv缓冲区并不会导致send()挂起-恰恰相反。

OP中没有提到发送和接收是否在同一进程中,更不用说是在同一线程中了。最后一句话完全是错误的:发送缓冲区已满不能导致recv()挂起。 - user207421
@EJP - OP中没有提到发送和接收发生在不同的进程中。此外,我明确地限定了我的答案适用于相同的执行线程情况下,_前提是..._而我描述的情况并不是发送缓冲区已满导致recv()挂起,而是send()挂起导致recv()未被调用。也许您可以重新阅读我的答案,并以此解释为依据。 - Armali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接