Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ IOCP WSARecv始终返回错误10022_C++_Windows_C++11_Iocp_Io Completion Ports - Fatal编程技术网

C++ IOCP WSARecv始终返回错误10022

C++ IOCP WSARecv始终返回错误10022,c++,windows,c++11,iocp,io-completion-ports,C++,Windows,C++11,Iocp,Io Completion Ports,我在Windows上使用IOCP。以前我使用方法GetQueuedCompletionStatus轮询队列,一切正常。但是,当我决定重构逻辑以利用带有WSARecv调用的完成例程时,它总是失败,错误为WSAEINVAL 10022。此代码位于使用CreateTread创建的线程中 工作例程为空,并具有以下定义: void static CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overl

我在Windows上使用IOCP。以前我使用方法GetQueuedCompletionStatus轮询队列,一切正常。但是,当我决定重构逻辑以利用带有WSARecv调用的完成例程时,它总是失败,错误为WSAEINVAL 10022。此代码位于使用CreateTread创建的线程中

工作例程为空,并具有以下定义:

void static CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags) {}
当我将NULL而不是WorkerRoutine传递给WSARecv方法时,一切正常。但当我将完成例程传递给调用时,它失败了,出现错误10022。我试着使用WorkerRoutine和&WorkerRoutine没有任何帮助


hEvent属性在重叠的_EX对象中设置为NULL。

与文件和lpCompletionRoutine关联的I/O完成端口这是互斥参数。你不能同时使用这两种语言。执行此操作时,内核返回STATUS\u INVALID\u参数,该参数被转换为WSAEINVAL。所以你必须得到这个错误

IOCP和APCProutine以两种不同的方式通知您操作完成。当您使用IOCP时-系统在完成时向IOCP发送数据包。以后需要使用GetQueuedCompletionStatus或NTremovieoCompletion来提取此数据包。这不是民意测验。如果使用apc例程系统,请从另一侧将apc插入线程。使用两种方式一次通知和并发通知-在本例中,当返回到您的状态\u INVALID\u参数时,这是逻辑错误和内核更正

不幸的是,MSDN中没有明确说明这一点,或者我无法回答这一点。但一些研究+WRK源代码有助于理解这种情况:

WSARecv在内部调用zwdeviceocontrolfile,并作为调用内核的结果。当lpCompletionRoutine!=0 IOPXXCONTROLFILE的APCPROUTE参数存在,您恰好在以下点失败:

还可以在堆栈中分配m_wsabuf。valid必须是指向WSABUF点的唯一缓冲区

如果此功能以重叠方式完成,则为 Winsock服务提供商捕获WSABUF的责任 在从此调用返回之前。这将启用应用程序 构建lpBuffers指向的基于堆栈的WSABUF数组 参数


因此,您可以放置到重叠的_EX only buffer中的哪个点WSABUF.buf,而不是整个WSABUF。但这与您的错误无关

与文件关联的I/O完成端口和lpCompletionRoutine这是互斥参数。你不能同时使用这两种语言。执行此操作时,内核返回STATUS\u INVALID\u参数,该参数被转换为WSAEINVAL。所以你必须得到这个错误

IOCP和APCProutine以两种不同的方式通知您操作完成。当您使用IOCP时-系统在完成时向IOCP发送数据包。以后需要使用GetQueuedCompletionStatus或NTremovieoCompletion来提取此数据包。这不是民意测验。如果使用apc例程系统,请从另一侧将apc插入线程。使用两种方式一次通知和并发通知-在本例中,当返回到您的状态\u INVALID\u参数时,这是逻辑错误和内核更正

不幸的是,MSDN中没有明确说明这一点,或者我无法回答这一点。但一些研究+WRK源代码有助于理解这种情况:

WSARecv在内部调用zwdeviceocontrolfile,并作为调用内核的结果。当lpCompletionRoutine!=0 IOPXXCONTROLFILE的APCPROUTE参数存在,您恰好在以下点失败:

还可以在堆栈中分配m_wsabuf。valid必须是指向WSABUF点的唯一缓冲区

如果此功能以重叠方式完成,则为 Winsock服务提供商捕获WSABUF的责任 在从此调用返回之前。这将启用应用程序 构建lpBuffers指向的基于堆栈的WSABUF数组 参数


因此,您可以放置到重叠的_EX only buffer中的哪个点WSABUF.buf,而不是整个WSABUF。但这与您的错误无关

这与文件无关,clientSocket讲述了Socket。在这里,我还找到了一个示例,该示例演示了如何将WorkerRoutine与事件一起使用,并且可以正常工作。另一方面,MSDN不同意他们的观点,所以我confused@htonus-套接字是文件。我什么也没写。我写道iocp和WorkerRoutine是互斥的。删除工作例程如果要在套接字上使用iocp,请将其设置为0。如果您想使用WorkerRoutine,也可以不将套接字绑定到iocp。我写的都是100%true@htonus-只要试着自己想一想-如果您想使用WorkerRoutine-您将IO完成端口与文件关联的内容?你不需要这个。从另一个方面——如果你有IOCP文件——你需要什么WorkerRoutine?删除这2个选项中的任何一个objects@htonus-我快速看一下你的例子-这里有一个很大的逻辑问题。它使用异步WSARecv-这没问题。但在此之前,它使用同步调用accept,这是wait,这是kill all逻辑。如果
你需要异步io-这里只使用AcceptEx是的,我知道。在我的应用程序中,我使用非阻塞套接字上的accept。所以它不会阻止执行。不管怎样,谢谢你的评论。这与文件无关,clientSocket讲述的是Socket。在这里,我还找到了一个示例,该示例演示了如何将WorkerRoutine与事件一起使用,并且可以正常工作。另一方面,MSDN不同意他们的观点,所以我confused@htonus-套接字是文件。我什么也没写。我写道iocp和WorkerRoutine是互斥的。删除工作例程如果要在套接字上使用iocp,请将其设置为0。如果您想使用WorkerRoutine,也可以不将套接字绑定到iocp。我写的都是100%true@htonus-只要试着自己想一想-如果您想使用WorkerRoutine-您将IO完成端口与文件关联的内容?你不需要这个。从另一个方面——如果你有IOCP文件——你需要什么WorkerRoutine?删除这2个选项中的任何一个objects@htonus-我快速看一下你的例子-这里有一个很大的逻辑问题。它使用异步WSARecv-这没问题。但在此之前,它使用同步调用accept,这是wait,这是kill all逻辑。如果您需要异步io-请仅使用此处的AcceptEx是的,我知道这一点。在我的应用程序中,我使用非阻塞套接字上的accept。所以它不会阻止执行。不管怎样,谢谢你的评论。
void static CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags) {}
    //
    // If this file has an I/O completion port associated w/it, then ensure
    // that the caller did not supply an APC routine, as the two are mutually
    // exclusive methods for I/O completion notification.
    //

    if (fileObject->CompletionContext && IopApcRoutinePresent( ApcRoutine )) {
        ObDereferenceObject( fileObject );
        return STATUS_INVALID_PARAMETER;
}