繁体   English   中英

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

[英]TCP server not accepting right number of connections issued by client with small listen backlog

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

但是在服务器程序accept 8800、9400(非固定)连接后,它只是停止接受任何新连接。 客户端使用阻塞connect建立连接,所有这10000个connect调用均成功返回。 然后,所有内容冻结,不再有数据包(没有重新传输),也没有更多的接受连接。

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

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

我知道,当接受队列已满时,Linux可能会忽略3Way握手的传入ACK ,保留客户端的连接已建立,但服务器的连接仍未建立,然后让重传机制起作用。 最终服务器重传SYN/ACK包,如果服务器的接受队列可用,则客户端以ACK响应以重新建立此连接。 如果队列中没有可用空间,则服务器将再次忽略该ACK

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

那么潜在的细节是什么?

这是我的代码: 客户端 服务器

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

在此处输入图片说明

激活SYN Flood后,将从客户端发送的所有ACK丢弃。 服务器仅向客户端发送了SYN / ACK和cookie,因此cookie缓存表将比套接字表小得多,以保持活动连接。 在这种情况下,在客户端,套接字被认为已建立,但在服务器端并没有真正打开任何东西(半开连接)。

当客户端应用程序关闭套接字时,带有ACK标志设置的FIN数据包将被发送到服务器,其中包含cookie,服务器将看到连接具有ACK,此时,如果积压未满,服务器将尝试从cookie重建连接。 如果cookie有效(在有效的往返时间内),则套接字将被添加到积压队列中,并且可以作为普通套接字进行处理。

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

暂无
暂无

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

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