我应该使用 AcceptEx() 还是 WSAAccept()?

Posted

技术标签:

【中文标题】我应该使用 AcceptEx() 还是 WSAAccept()?【英文标题】:Should I use AcceptEx() or WSAAccept()? 【发布时间】:2015-02-25 13:06:41 【问题描述】:

我正在使用 Overlapped IO,我想使用阻塞调用来接受客户端连接,就像我使用普通的 accept() 一样。我不确定,但我认为AcceptEx() 不会阻止,而WSAAccept() 会。那么WSAAccept() 是否与accept() 相似?

【问题讨论】:

【参考方案1】:

accept()WSAAccept() 都会阻塞,除非您使用 ioctlsocket 将侦听器设置为非阻塞模式。因此,您可以在阻塞时使用其中任何一个来接受客户端。

但是,如果您使用WSAEventSelect 在侦听器上针对FD_ACCEPT 注册事件,您将获得更多控制权。当客户准备好接受无阻塞时,您的事件将被设置。

然后,您可以将此事件与超时或其他事件结合起来,如果您想在调用 WaitForMultipleObjectsEx 时取消侦听(例如在应用程序退出时),您可以发出信号。

【讨论】:

【参考方案2】:

为什么要使用阻塞调用?

如果您使用的是 I/O 完成端口,那么处理连接建立的最佳方法是使用AcceptEx(),而不是在连接时等待数据。这样做的原因是使用AcceptEx() 意味着您不需要单独的线程来处理连接建立(即正常的“接受循环”),从而减少了不必要的上下文切换。

AcceptEx() 的“接受并读取数据”选项可能会在连接连接但不发送数据的情况下使您面临拒绝服务攻击,并且很难防范它,除非您添加一个可以破坏首先使用AcceptEx()的目的......

【讨论】:

"AcceptEx() 的“接受和读取数据”选项可能会使您面临拒绝服务攻击" 那我为什么要使用AcceptEx()?! 你应该使用它,因为它不需要有一个专用的接受线程和所有产生的(和毫无意义的)上下文切换。 但是你说“它可以让你面临拒绝服务攻击”。 仅当您还等待数据时。您可以使用 AcceptEx() 并提供一个缓冲区,该缓冲区将仅包含地址而不提供数据空间,并且可以作为重叠接受并且没有 DOS 问题。

以上是关于我应该使用 AcceptEx() 还是 WSAAccept()?的主要内容,如果未能解决你的问题,请参考以下文章

IOCP、AcceptEx、重叠和 WSAEINVAL

AcceptEx()同步完成?

IOCP AcceptEx 在连接时未创建完成

Apache - AH00341:winnt_accept:异步 AcceptEx 失败

关闭尚未完成 AcceptEx 的套接字 - 如果以及如何?

AcceptEx与完成端口结合实例