1

我正在通过这篇文章阅读有关 IOCP 的信息

http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5i.html

他使用的第一个 WSARecv 函数与 0lpNumberOfBytesRecvd一起用于启动完成端口

if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags, &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)

            {

                        if (WSAGetLastError() != ERROR_IO_PENDING)

                        {

                                    printf("WSARecv() failed with error %d\n", WSAGetLastError());

                                    return 1;

                        }

            }

            else

                        printf("WSARecv() is OK!\n");

}

现在在应用程序接收 IO 帖子的工作线程函数上

它也检查 0 的参数lpNumberOfBytesGetQueuedCompletionStatus如果是则关闭连接

// First check to see if an error has occurred on the socket and if so

                        // then close the socket and cleanup the SOCKET_INFORMATION structure

                        // associated with the socket

                        if (BytesTransferred == 0)

当我尝试它时,第一条 IOCP 消息发布了GetQueuedCompletionStatus它总是在lpNumberOfBytes参数中返回 0 的函数,因为第一次WSARecv调用是在lpNumberOfBytesRecvd设置为零的情况下调用的

我已尝试实现此代码,但我无法使代码正常工作,除非我在第一次调用时选择不在此参数中使用 NULL,WSARecv以便 在收到所有数据的情况下可以使用GetQueuedCompletionStatus返回值 0 的函数lpNumberOfBytes.

MSDN 说要使用 NULL

lpNumberOfBytesRecvd [出]

如果接收操作立即完成,则指向此调用接收的数据数(以字节为单位)的指针。

如果 lpOverlapped 参数不为 NULL,则为此参数使用 NULL 以避免潜在的错误结果。仅当 lpOverlapped 参数不为 NULL 时,此参数才能为 NULL。

如果我WSARecv再次调用(在工作线程函数内部)并且收到所有数据,则代码无法正常工作,这会导致GetQueuedCompletionStatus函数立即返回而无需等待,即使使用了 INFINITE 并且工作线程进入无限循环。函数没有返回任何错误,GetQueuedCompletionStatus它只是表现得好像有更多数据但没有。

WSARecv需要以 buf 大小的什么值启动?

我也应该使用非阻塞套接字吗?或者只是普通的阻塞套接字,因为我使用单独的线程来接受连接,所以我认为它很好,因为它不会冻结我的 GUI。

4

0 回答 0