gpt4 book ai didi

tcp - 在接受之前拒绝 TCP 连接?

转载 作者:可可西里 更新时间:2023-11-01 02:30:18 25 4
gpt4 key购买 nike

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

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

我不太了解 TCP 的内部工作原理,无法判断在连接被接受之前拒绝连接和在连接建立后立即断开套接字之间实际上有什么区别吗?如果有,是否有任何方法可以使用 AcceptEx 模拟 WSAAccept 功能?

有人可以阐明这个问题吗?

最佳答案

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

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

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

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

但是,在 Windows 上,SO_CONDITIONAL_ACCEPT 调用允许应用程序控制积压队列。这意味着服务器不会对SYN 数据包做出任何 响应,直到应用程序对连接进行操作。这意味着,在此级别拒绝连接实际上可以在不创建状态的情况下向网络发送 RST 数据包。

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

关于tcp - 在接受之前拒绝 TCP 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1752219/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com