Language agnostic 更多TCP和POSIX套接字listen()和accept()语义
情况:服务器调用listen()(但不调用accept()!)。客户端向服务器发送一个SYN。服务器获取SYN,然后将SYN/ACK发送回客户端。但是,客户机现在挂起/挂断,因此它从不向服务器发送ACK。连接处于SYN_发送状态 现在,另一个客户机发送一个SYN,从服务器返回一个SYN/ACK,并返回一个ACK。此连接现在处于已建立状态Language agnostic 更多TCP和POSIX套接字listen()和accept()语义,language-agnostic,sockets,network-programming,tcp,Language Agnostic,Sockets,Network Programming,Tcp,情况:服务器调用listen()(但不调用accept()!)。客户端向服务器发送一个SYN。服务器获取SYN,然后将SYN/ACK发送回客户端。但是,客户机现在挂起/挂断,因此它从不向服务器发送ACK。连接处于SYN_发送状态 现在,另一个客户机发送一个SYN,从服务器返回一个SYN/ACK,并返回一个ACK。此连接现在处于已建立状态 现在,服务器最终调用accept()。会发生什么?在出现某种超时之前,accept()是否会阻止第一个错误连接?它是否首先检查队列中是否存在任何已建立的连接并返
现在,服务器最终调用accept()。会发生什么?在出现某种超时之前,accept()是否会阻止第一个错误连接?它是否首先检查队列中是否存在任何已建立的连接并返回这些连接?好的,您在这里描述的是一个典型的syn洪水攻击(),当执行多次时 例如:有两个独立的队列,一个syn队列和一个已建立的队列。显然,第一个连接将保留在syn队列中(因为它处于syn_RCVD状态),第二个连接将位于accept()将从中获取它的已建立队列中。netstat仍应在SYN_RCVD状态下显示第一个
注意:另请参见我的评论,客户端将处于SYN_发送状态,服务器(我们正在讨论)将处于SYN_RCVD状态。您必须记住,
侦听()
,接受()
等都不是隐藏协议调试工具。从accept
手册页:“accept-接受套接字上的连接”。不报告不完整的连接,也不应该报告。应用程序不需要担心套接字的设置和拆卸,或重传,或片段重组,或
如果您正在编写一个网络应用程序,那么涵盖您应该关注的内容就足够了。如果你有一个正常工作的应用程序,但正在试图找出问题,那么就使用一个好的网络调试工具,检查操作系统状态的工具,等等。不要试图把它放在你的应用程序中
如果您试图编写调试工具,那么使用应用程序级TCP/IP调用无法完成您想要的任务。您需要至少降低一个级别。您应该注意,在某些实现中,半开放连接(处于SYN_RCVD状态的连接)甚至可能不会记录在服务器上。实现可以使用,其中它们将完成建立连接所需的所有信息编码到SYN+ACK数据包的序列号中。当ACK数据包返回时,序列号增加,他们可以减少它并返回信息。这可以通过不为这些半开放连接分配服务器上的任何资源来帮助防止SYN洪水;因此,无论客户端发送多少额外的SYN数据包,服务器都不会耗尽资源 请注意,实现了4路握手,协议中内置了cookie,以防止SYN洪水,同时允许在cookie中存储更多信息,因此不必限制支持的协议功能,因为cookie的大小太小(在TCP中,您只获得32位序列号来存储所有信息)
因此,为了回答您的问题,用户空间
accept()
将只看到完全建立的连接,而不知道半开放的连接纯粹是TCP堆栈的一个实现细节。当服务器获取SYN并发送SYN/ACK返回时,连接(从服务器角度看)处于SYN_RCVD状态。客户端处于SYN_SENT状态,这与讨论无关。不,在服务器发送SYN/ACK之后,它也处于SYN_SENT状态。哦,抱歉-看起来你是对的。我可能必须修复代码-谢谢!我正在实现listen()和accept()我自己在做一个项目,所以我必须知道他们的行为。