我试图了解BSD套接字接口中的事件如何转换为TCP连接的状态。特别是,我试图了解accept()在服务器端返回连接进程的哪个阶段
accept()返回这些步骤中的哪一个?
发布于 2011-06-28 21:20:37
accept在连接完成后返回。客户端发送他的ACK后,连接就完成了。
accept为您提供了一个可以进行通信的套接字。当然你知道,在连接建立之前,你是无法沟通的。在握手之前不能建立联系。
在客户感觉到他的ACK之前返回是没有意义的。这完全有可能,他不会说什么后,最初的SYN。
发布于 2011-06-29 12:16:50
内核normally1中的TCP/IP堆栈代码完全完成了三方握手,而不需要任何用户空间代码的干预。列出的三个步骤都发生在accept()返回之前。事实上,它们可能在accept()被调用之前就已经发生了!
当将堆栈告诉listen()以获取特定TCP端口上的连接时,传递一个backlog参数,该参数告诉内核可以同时代表程序默默地接受多少连接。当内核自动接受新的连接请求时,就会使用这个队列,并在那里保存这些请求,直到您的程序有时间对它们进行accept()处理。当调用accept()时,在侦听待办事项队列中有一个或多个连接时,只会从队列中删除最旧的连接并绑定到新的套接字。
换句话说,如果您的程序调用listen(sd, 5),那么将进入一个无限的不操作循环,使其永远不会调用accept(),从客户端的角度来看,五个并发客户端连接请求将成功。第六个连接请求将在第一个SYN数据包上停止,直到拥有TCP端口的程序调用accept()或另一个客户端放弃其连接为止。
当然,防火墙和其他堆栈修改可以改变这种行为。我在这里只谈到默认的BSD套接字堆栈行为。
2如果调用accept()时在待办事项处理中没有等待连接,则默认情况下它会阻塞,除非监听器套接字设置为非阻塞,在这种情况下,它返回-1,而errno是EWOULDBLOCK。
https://stackoverflow.com/questions/6513207
复制相似问题