accept
winsock 有3个不同的版本.除了accept
标准合规的基本内容之外,还有AcceptEx
最先进的版本(由于它具有重叠的io功能),以及WSAAccept
.后者支持条件回调,据我所知,它允许在接受之前拒绝连接请求(当SO_CONDITIONAL_ACCEPT
启用该选项时).其他任何版本都不支持此功能.
由于我更喜欢使用AcceptEx
重叠的io,我想知道为什么这个功能只能在更简单的版本中使用?
我不太了解TCP的内部工作原理,告诉我们在接受连接之前拒绝连接和在连接建立后立即断开连接之间实际上有什么区别?如果有,有没有办法模仿WSAAccept
功能AcceptEx
?
有人能否对这个问题有所了解?
Nak*_*ble 18
建立连接后,远程端发送一个设置了SYN标志的数据包.服务器使用SYN,ACK数据包进行应答,然后远程端发送一个ACK数据包,该数据包可能已包含数据.
有两种方法可以打破TCP连接.第一种是重置连接 - 这与连接到没有人正在侦听的端口时看到的常见"连接被拒绝"消息相同.在这种情况下,原始SYN数据包用RST数据包回答,该数据包立即终止连接并且是无状态的.如果重新发送SYN,将从每个收到的SYN数据包生成RST.
第二种是在连接形成后立即关闭连接.在TCP级别上,无法立即双向关闭连接 - 您唯一可以说的是"我不会再发送任何数据".发生这种情况时,当初始SYN,SYN,ACK,ACK交换完成时,服务器将FIN数据包发送到远程端.在大多数情况下,告诉FIN的另一端"我不会再发送任何数据"会使另一端关闭连接,并发送它自己的FIN数据包.以这种方式终止的连接与由于某种原因没有发送数据的普通连接没有任何不同.这意味着TCP连接的正常状态跟踪和延迟关闭状态将保持不变,就像正常连接一样.
现在,在C API方面,这看起来有点不同.在调用listen()
端口时,操作系统开始接受该端口上的连接.这意味着无论C代码是否已调用,它都会开始向连接回复SYN,ACK数据包accept()
.因此,在TCP方面,在接受之前或之后连接是否以某种方式关闭没有区别.另一个值得关注的问题是,侦听套接字有一个积压,这意味着在开始向远程端发送RST之前,它可以等待的未接受连接数.
但是,在Windows上,该SO_CONDITIONAL_ACCEPT
调用允许应用程序控制积压队列.这意味着在应用程序对连接执行某些操作之前,服务器不会对SYN数据包进行任何回答.这意味着,拒绝此级别的连接实际上可以在不创建状态的情况下将RST数据包发送到网络.
因此,如果您无法SO_CONDITIONAL_ACCEPT
以某种方式在正在使用的套接字上启用该功能AcceptEx
,它将以不同的方式显示在网络上.然而,实际上并没有很多地方使用直接的RST功能,所以我认为对此的要求必然意味着一个非常专业的系统.对于大多数常见用例,接受套接字然后关闭它是正常的行为方式.
归档时间: |
|
查看次数: |
11777 次 |
最近记录: |