Network programming AcceptEx()同步完成?

Network programming AcceptEx()同步完成?,network-programming,winsock,winsock2,iocp,Network Programming,Winsock,Winsock2,Iocp,在学习服务器的同时,我正在使用IO完成端口和AcceptEx,我正在学习的免费服务器框架就是这样做的。他有以下代码: // Basically calls AcceptEx() via a previously obtained function pointer if (!CMSWinSock::AcceptEx( m_listeningSocket, pSocket->m_socket, reinterpret_cast<void*>(co

在学习服务器的同时,我正在使用IO完成端口和AcceptEx,我正在学习的免费服务器框架就是这样做的。他有以下代码:

// Basically calls AcceptEx() via a previously obtained function pointer
if (!CMSWinSock::AcceptEx(
      m_listeningSocket,
      pSocket->m_socket,
      reinterpret_cast<void*>(const_cast<BYTE*>(pBuffer->GetBuffer())),
      bufferSize,
      sizeOfAddress,
      sizeOfAddress,
      &bytesReceived,
      pBuffer))
   {
      const DWORD lastError = ::WSAGetLastError();

      if (ERROR_IO_PENDING != lastError)
      {
         Output(_T("CSocketServerEx::Accept() - AcceptEx: ") + GetLastErrorMessage(lastError));

         pSocket->Release();           
         pBuffer->Release();
      }
   }
   else
   {
      // Accept completed synchronously. We need to marshal the data recieved over to the 
      // worker thread ourselves...

      m_iocp.PostStatus((ULONG_PTR)m_listeningSocket, bytesReceived, pBuffer);
   }
我对接受同步完成的else案例感到困惑。我曾多次尝试通过在发出AcceptEx之前暂停代码,连接,然后恢复代码来命中此代码路径,但每当我尝试调用时,调用总是失败,并出现错误,我会收到通知包。此外,我读过一些我可能误解了哪些国家的文章

此外,如果Winsock2 I/O调用返回成功或IO_挂起,则 保证在以下情况下完成数据包将排队到IOCP I/O完成

但是,我认为这不适用于AcceptEx,因为参数lpdwBytesReceived的for-AcceptEx状态

仅当操作同步完成时,才设置此参数

所以它似乎可以同步完成…有人能告诉我AcceptEx如何同步完成,即如何在我的服务器中复制它吗

此外,如果Winsock2 I/O调用返回SUCCESS或ERROR\u IO\u PENDING,则 保证在以下情况下完成数据包将排队到IOCP I/O完成

如果完成端口与文件关联,则这适用于任何I/O请求。但从windows vista开始,这也取决于文件句柄的设置

但首先需要从本机视图开始查看

默认情况下,如果未设置文件\u跳过\u完成\u端口\u成功,则按返回的NTSTATUS状态存在3个案例:

NT\u成功状态或状态>=0-将完成 NT\u ERRORstatus或status>=0xc0000000-将不会完成 NT\u警告状态或状态<0xc0000000-不清楚-如果 来自I/O管理器的错误表示-状态\u数据类型\u未对齐-将 不可能完成。如果此错误来自驱动程序,请说 状态\u没有\u更多\u文件-将完成。 win32层通常单独检查状态_PENDING和返回错误_IO_PENDING(在本例中),但存在和异常,如ReadDirectoryChangesW。否则,如果NT\U ERRORstatus api返回失败并设置错误代码。否则返回成功。可见,在这种情况下,NT_WARNINGstatus被认为是成功的,但在这种情况下,如果I/O管理器出现错误,将无法完成。如果参数不正确,I/O通常从NT\U ERRORstatus范围返回错误。当i/O管理器有关于缓冲区对齐的专门知识时,我所知道的异步api的唯一情况—状态\数据类型\未对齐可以在错误对齐的缓冲区中返回。在NtNotifyChangeDirectoryFile中 win32或NtQueryDirectoryFile的ReadDirectoryChangesW没有对应的win32 api。所以,我知道的唯一一种情况是,当win32返回成功时——使用未对齐的lpBuffer调用ReadDirectoryChangesW,它必须是DWORD对齐的——在这种情况下,i/O管理器只返回状态\数据类型\未对齐,但win32层将其解释为成功代码并返回true。但在这种情况下将无法完成。然而,这种情况很少发生,您可能需要为此使用错误的对齐结构。所以一般来说是的:

默认情况下,如果I/O调用返回成功或错误,IO挂起将排队等待端口的完成条目。我试着描述一个特殊的例外情况

如果我们在文件对象上设置文件跳过完成端口成功注意这是每个文件对象,而不是每个文件句柄-此处的文档不完全是更简单和有效的-完成条目将排队到端口-当且仅当I/O请求返回挂起状态时。win32视图中的错误\u IO\u挂起,除了ReadDirectoryChangesW可能还有其他api?其中win32层只是丢失了返回代码信息

然而,我认为这不适用于AcceptEx

你错了。我是这么说的,这适用于任何io请求。此参数仅在操作同步完成时设置。-那又怎样

若查看代码段,请清除可见的代码假定—在AcceptEx已完成同步且未发生错误的情况下—将不会有io完成。或SetFileCompletionNotificationModesm\u ListingSocket、文件跳过\u完成\u端口\u成功调用或代码错误-在这种情况下将是io完成,不需要m\u iocp.PostStatus-这是致命错误。然而,我怀疑代码在成功时使用了文件跳过端口,所以这是错误的。但从未出现错误,因为AcceptEx在ioctl下面加下划线的驱动程序端实现从未返回状态\u SUCCESS:它检查参数-如果错误-只返回一些错误,否则总是返回状态\u PENDING。因此,对于异步套接字,AcceptEx永远不会返回true,代码永远不会跳转到error-else情况。但无论如何,代码是错误的。此外,我认为设计不是最好的-如果我们确定没有完成-更好的是直接调用完成例程,返回错误代码,而不是释放-这将在完成例程或PostStatus中完成-为了什么帖子呼叫di 矩形

AcceptEx如何同步完成

非常简单-如果m_ListingSocket是同步文件对象的句柄。但是,在这种情况下,不能将IOCP绑定到文件,只能在异步文件对象的情况下进行绑定

关于lpdwBytesReceived参数-系统复制信息成员或如果希望重叠。InternalHigh,以防操作刚刚完成。在等待返回的情况下-此数据未准备就绪且未填充。您得到了io在完成时返回的实际字节数