gpt4 book ai didi

c++ - TCP 服务器不接受客户端发出的正确数量的连接,具有少量监听积压

转载 作者:太空宇宙 更新时间:2023-11-04 10:04:26 24 4
gpt4 key购买 nike

我编写了一个简单的客户端程序,在非常短的时间内使用 100 个线程发出总共 10000 个连接。一个简单的服务器程序将 listen backlog 设置为 20,使用 epoll 来接受任何新连接并记录总连接数。我使用 ulimit -n 来确保它大于 20000,因此应该有足够的 fd 资源。

但在服务器程序接受像 8800、9400(不固定)连接后,它就停止接受任何新连接。客户端使用阻塞式connect建立连接,这10000次connect调用全部返回成功。然后一切都卡住了,没有更多的数据包(没有重传),没有更多接受的连接。

但是一旦我关闭客户端程序,服务器程序在关闭一些连接后开始接受剩余的连接(并最终接受所有10000个连接并关闭所有这些连接)。

当我将 backlog 更改为 100 或更大时,所有 10000 个连接都被毫无问题地接受了。 (所以不是fd资源问题)

我知道当接受队列已满时,linux 可能只是忽略传入的 3 次握手的 ACK,让客户端的连接建立但服务器的连接仍未建立,然后让重传机制工作。最终服务器重传SYN/ACK数据包,如果服务器的接受队列可用,客户端响应ACK重新建立连接。如果队列中没有可用空间,服务器将再次忽略 ACK

但是当我使用wireshark监控这些重传时,我发现只有少量的SYN/ACK重传发生(大约100~200,远小于丢失的连接数,介于500~1500),重传一次或两次,均小于/proc/sys/net/ipv4/tcp_synack_retries中指定的值。我检查了其中一些重传的 SYN/ACK 数据包,所有这些数据包都收到了来自客户端的 ACK。但是客户端重传的SYN包数量很大。

那么底层的细节是什么?

这是我的代码: client server

最佳答案

当积压已满且启用SYN cookies时,内核将激活临时SYN泛洪模式。此图显示了 cookie 的工作方式 (source):

enter image description here

当 SYN flood 被激活时,所有从客户端发送的 ACK 将被丢弃。服务器只向客户端发送 SYN/ACK 和 cookie,cookie 缓存表将比 socket 表小得多以维持事件连接。在这种情况下,在客户端,套接字被认为已建立,但在服务器端没有真正打开任何东西(半开连接)。

当客户端应用关闭socket时,会向服务器发送一个设置了ACK标志的FIN包,里面有cookie,服务器看到连接有ACK,此时,如果积压未满,服务器将尝试从 cookie 重建连接。如果 cookie 有效(在有效的往返行程内),套接字将被添加到积压队列中,并且可以作为普通套接字处理。

这意味着,当 SYN cookie 模式被激活且积压队列未满时,如果客户端通过半开套接字向服务器发送一些数据,accept() 函数将返回新的传入连接。

关于c++ - TCP 服务器不接受客户端发出的正确数量的连接,具有少量监听积压,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53580682/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com