据我所知,一旦我们用绑定套接字完成'listen'调用,客户端发起的所有TCP连接都会开始成功,但是,当调用accept时,有很多可能性接受调用可能会失败(由于不可用的内存或超出限制的文件描述符等)。
我在solaris中运行了一些简单的测试。
服务器: 1.使用ulimit命令将文件描述符的最大数量减少到8
将积压设置为听取8。
听一听。
在循环中调用accept 8次,然后进入睡眠状态
客户端:
连接8个连接。
进入睡眠状态
测试结果:
在客户端,所有连接都通过。 在服务器端,接受传递仅为4,而失败为4.(这是合理的,考虑到3个文件描述符用于标准,一个用于侦听,然后只有4个连接的空间)。但是,netstat显示已建立的所有8个连接。
TCP转储,显示所有8个连接的3次握手成功。服务器何时通知客户端上的4个连接已失败? (即什么时候会向他们发送FIN?)
我注意到了另一种行为,一旦服务器进入休眠状态,然后如果我通过执行CTRL + C来终止进程,那么我发现正在为这4个失败的连接发送FIN。
我对这种行为有点困惑。非常感谢任何帮助。
答案 0 :(得分:2)
根据您的描述,我的猜测是操作系统确实建立了所有8个连接,并将缓冲客户端发送的任何数据(最大窗口大小)。一旦您的服务器释放了一些FD并且能够接受挂起的连接,您应该能够读取在此之前发送的任何内容。这也可以解释为什么在您的进程被终止时终止连接。
简而言之:连接确实存在,但是你的程序无法使用它们,因为它没有免费的FD。