在TCP连接之前拒绝它';什么被接受了?

在TCP连接之前拒绝它';什么被接受了?,tcp,winsock,Tcp,Winsock,winsock中有3个不同的accept版本。除了基本的accept符合标准之外,还有AcceptEx似乎是最高级的版本(由于它的io功能重叠),还有wsaaaccept。后者支持条件回调,据我所知,它允许在接受连接请求之前拒绝连接请求(当启用了SO\u CONDITIONAL\u ACCEPT选项时)。其他版本均不支持此功能 由于我更喜欢使用重叠io的AcceptEx,我想知道为什么这个功能只在更简单的版本中可用 我对TCP的内部工作原理了解不够,无法告诉wehter在接受连接之前拒绝连接和在

winsock中有3个不同的
accept
版本。除了基本的
accept
符合标准之外,还有
AcceptEx
似乎是最高级的版本(由于它的io功能重叠),还有
wsaaaccept
。后者支持条件回调,据我所知,它允许在接受连接请求之前拒绝连接请求(当启用了
SO\u CONDITIONAL\u ACCEPT
选项时)。其他版本均不支持此功能

由于我更喜欢使用重叠io的
AcceptEx
,我想知道为什么这个功能只在更简单的版本中可用

我对TCP的内部工作原理了解不够,无法告诉wehter在接受连接之前拒绝连接和在建立连接之后立即断开套接字之间实际上有什么区别?如果有,是否有任何方法可以通过
AcceptEx
模拟
wsaaaccept
功能


有人能解释一下这个问题吗?

我不能评论Windows方面的事情,但就TCP而言,拒绝连接与断开连接有点不同


例如,断开连接意味着网络和主机中已经“消耗”了更多的资源(例如防火墙和端点中维护的端口状态、交换机/路由器中使用的转发容量等)拒绝连接的资源密集度较低。

建立连接后,远程端发送设置了SYN标志的数据包。服务器用一个SYN,ACK数据包进行应答,然后远程端发送一个ACK数据包,该数据包可能已经包含数据

有两种方法可以阻止TCP连接的形成。第一个是重置连接-这与连接到无人监听的端口时看到的常见“连接被拒绝”消息相同。在这种情况下,原始的SYN数据包用RST数据包应答,该数据包立即终止连接,并且是无状态的。如果重新发送SYN,将从每个接收到的SYN数据包生成RST

第二种方法是在连接形成后立即关闭连接。在TCP级别上,无法立即关闭双向连接-您唯一可以说的是“我不会再发送任何数据”。这样,当初始SYNSYN,ACKACK交换完成时,服务器向远程端发送FIN数据包。在大多数情况下,用FIN告诉另一端“我不会再发送任何数据”会使另一端也关闭连接,并发送自己的FIN数据包。以这种方式终止的连接与由于某种原因未发送数据的正常连接没有任何区别。这意味着TCP连接的正常状态跟踪和延迟关闭状态将保持不变,就像正常连接一样

现在,在C API方面,这看起来有点不同。在端口上调用
listen()
时,操作系统开始接受该端口上的连接。这意味着,无论C代码是否调用了
accept()
,is都会开始向连接回复SYN,ACK数据包。因此,在TCP端,无论是在接受之前还是之后以某种方式关闭连接,都没有区别。唯一的额外问题是侦听套接字有一个积压,这意味着在它开始对远程端说RST之前,它可以等待的不可接受的连接数

但是,在windows上,
SO\u CONDITIONAL\u ACCEPT
调用允许应用程序控制待办事项队列。这意味着,在应用程序对连接执行某些操作之前,服务器不会对SYN数据包应答任何内容。这意味着,拒绝此级别的连接实际上可以向网络发送RST数据包,而无需创建状态

因此,如果您无法在您正在使用的
AcceptEx
开启的套接字上以某种方式启用
So\u CONDITIONAL\u ACCEPT
功能,它将以不同的方式显示在网络上。然而,实际上没有多少地方使用即时RST功能,因此我认为这一要求必须意味着一个非常专门的系统。对于大多数常见的用例,接受套接字然后关闭它是正常的行为方式