⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overlap.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    WSAOVERLAPPEDPLUS *op=NULL;

    EnterCriticalSection(&gOverlappedCS);

    op = PendingStart;
    if (PendingStart)
    {
        PendingStart = op->next;
    }
    if (op == PendingEnd)
    {
        PendingStart = PendingEnd = NULL;
    }

    LeaveCriticalSection(&gOverlappedCS);

    return op;
}

//
// Function: ExecuteOverlappedOperation
//
// Description:
//    This function actually executes an overlapped operation that was queued.
//    If on Win9x we substitute our own completion function in order to intercept
//    the results. If on NT we post the operation to our completion port.
//    This function either returns NO_ERROR if the operation succeeds immediately
//    or the Winsock error code upone failure (or overlapped operation).
//
int ExecuteOverlappedOperation(WSAOVERLAPPEDPLUS *ol, BOOL bSynchronous)
{
    LPWSAOVERLAPPED_COMPLETION_ROUTINE   routine = NULL;
    PROVIDER                            *Provider;
    OVERLAPPED                          *col = NULL;
    DWORD                               *lpdwFlags = NULL,
                                        *lpdwBytes = NULL;
    int                                  ret=SOCKET_ERROR, err=0;

    if (!ghIocp)
        routine = IntermediateCompletionRoutine;

    Provider = ol->Provider;
    //
    // Reset the event handle if present. The handle is masked with 0xFFFFFFFE in
    //  order to zero out the last bit. If the last bit is one and the socket is
    //  associated with a compeltion port then when an overlapped operation is 
    //  called, the operation is not posted to the IO completion port.
    //
    if (ol->lpCallerOverlapped->hEvent != NULL)
    {
        ULONG_PTR   ptr=1;

        ResetEvent((HANDLE)((ULONG_PTR)ol->lpCallerOverlapped->hEvent & ~ptr));
    }

    switch (ol->Operation)
    {
        case LSP_OP_IOCTL:
            lpdwFlags = NULL;
            lpdwBytes = &ol->IoctlArgs.cbBytesReturned;
            ret = Provider->NextProcTable.lpWSPIoctl(
                    ol->ProviderSocket,
                    ol->IoctlArgs.dwIoControlCode,
                    ol->IoctlArgs.lpvInBuffer,
                    ol->IoctlArgs.cbInBuffer,
                    ol->IoctlArgs.lpvOutBuffer,
                    ol->IoctlArgs.cbOutBuffer,
                   &ol->IoctlArgs.cbBytesReturned,
                   &ol->ProviderOverlapped,
                    routine,
                    ol->lpCallerThreadId,
                   &ol->Error
                   );
            break;                         
        case LSP_OP_RECV:
            lpdwFlags = &ol->RecvArgs.dwFlags;
            lpdwBytes = &ol->RecvArgs.dwNumberOfBytesRecvd;
            ret = Provider->NextProcTable.lpWSPRecv(
                    ol->ProviderSocket,
                    ol->RecvArgs.lpBuffers,
                    ol->RecvArgs.dwBufferCount,
                   &ol->RecvArgs.dwNumberOfBytesRecvd,
                   &ol->RecvArgs.dwFlags,
                   &ol->ProviderOverlapped,
                    routine,
                    ol->lpCallerThreadId,
                   &ol->Error
                    );
            break;
        case LSP_OP_RECVFROM:
            lpdwFlags = &ol->RecvFromArgs.dwFlags;
            lpdwBytes = &ol->RecvFromArgs.dwNumberOfBytesRecvd;
            ret = Provider->NextProcTable.lpWSPRecvFrom(
                    ol->ProviderSocket,
                    ol->RecvFromArgs.lpBuffers,
                    ol->RecvFromArgs.dwBufferCount,
                   &ol->RecvFromArgs.dwNumberOfBytesRecvd,
                   &ol->RecvFromArgs.dwFlags,
                    ol->RecvFromArgs.lpFrom,
                    ol->RecvFromArgs.lpFromLen,
                   &ol->ProviderOverlapped,
                    routine,
                    ol->lpCallerThreadId,
                   &ol->Error
                    );
            break;
        case LSP_OP_SEND:
            lpdwFlags = &ol->SendArgs.dwFlags;
            lpdwBytes = &ol->SendArgs.dwNumberOfBytesSent;
            ret = Provider->NextProcTable.lpWSPSend(
                    ol->ProviderSocket,
                    ol->SendArgs.lpBuffers,
                    ol->SendArgs.dwBufferCount,
                   &ol->SendArgs.dwNumberOfBytesSent,
                    ol->SendArgs.dwFlags,
                   &ol->ProviderOverlapped,
                    routine,
                    ol->lpCallerThreadId,
                   &ol->Error
                   );
             break;
        case LSP_OP_SENDTO:
            lpdwFlags = &ol->SendToArgs.dwFlags;
            lpdwBytes = &ol->SendToArgs.dwNumberOfBytesSent;
            ret = Provider->NextProcTable.lpWSPSendTo(
                    ol->ProviderSocket,
                    ol->SendToArgs.lpBuffers,
                    ol->SendToArgs.dwBufferCount,
                   &ol->SendToArgs.dwNumberOfBytesSent,
                    ol->SendToArgs.dwFlags,
                    (SOCKADDR *)&ol->SendToArgs.To,
                    ol->SendToArgs.iToLen,
                   &ol->ProviderOverlapped,
                    routine,
                    ol->lpCallerThreadId,
                   &ol->Error
                    );
            break;
        case LSP_OP_TRANSMITFILE:
            lpdwFlags = &ol->TransmitFileArgs.dwFlags;
            lpdwBytes = NULL;
            ret = Provider->NextProcTableExt.lpfnTransmitFile(
                    ol->ProviderSocket,
                    ol->TransmitFileArgs.hFile,
                    ol->TransmitFileArgs.nNumberOfBytesToWrite,
                    ol->TransmitFileArgs.nNumberOfBytesPerSend,
                   &ol->ProviderOverlapped,
                    ol->TransmitFileArgs.lpTransmitBuffers,
                    ol->TransmitFileArgs.dwFlags
                    );
            if (ret == FALSE)
            {
                ret = SOCKET_ERROR;
                ol->Error = WSAGetLastError();
                WSASetLastError(ol->Error);
            }
            else
                ret = NO_ERROR;
            break;
        case LSP_OP_ACCEPTEX:
            lpdwFlags = NULL;
            lpdwBytes = &ol->AcceptExArgs.dwBytesReceived;
            ret = Provider->NextProcTableExt.lpfnAcceptEx(
                    ol->ProviderSocket,
                    ol->AcceptExArgs.sProviderAcceptSocket,
                    ol->AcceptExArgs.lpOutputBuffer,
                    ol->AcceptExArgs.dwReceiveDataLength,
                    ol->AcceptExArgs.dwLocalAddressLength,
                    ol->AcceptExArgs.dwRemoteAddressLength,
                   &ol->AcceptExArgs.dwBytesReceived,
                   &ol->ProviderOverlapped
                    );
            if (ret == FALSE)
            {
                ret = SOCKET_ERROR;
                ol->Error = WSAGetLastError();
                WSASetLastError(ol->Error);
            }
            else
                ret = NO_ERROR;
            break;
        case LSP_OP_CONNECTEX:
            lpdwFlags = NULL;
            lpdwBytes = &ol->ConnectExArgs.dwBytesSent;
            ret = Provider->NextProcTableExt.lpfnConnectEx(
                    ol->ProviderSocket,
                    (SOCKADDR *)&ol->ConnectExArgs.name,
                    ol->ConnectExArgs.namelen,
                    ol->ConnectExArgs.lpSendBuffer,
                    ol->ConnectExArgs.dwSendDataLength,
                   &ol->ConnectExArgs.dwBytesSent,
                   &ol->ProviderOverlapped
                    );
            if (ret == FALSE)
            {
                ret = SOCKET_ERROR;
                ol->Error = WSAGetLastError();
                WSASetLastError(ol->Error);
            }
            else
                ret = NO_ERROR;
            break;
        case LSP_OP_DISCONNECTEX:
            lpdwFlags = &ol->DisconnectExArgs.dwFlags;
            lpdwBytes = NULL;
            ret = Provider->NextProcTableExt.lpfnDisconnectEx(
                    ol->ProviderSocket,
                   &ol->ProviderOverlapped,
                    ol->DisconnectExArgs.dwFlags,
                    ol->DisconnectExArgs.dwReserved
                    );
            if (ret == FALSE)
            {
                ret = SOCKET_ERROR;
                ol->Error = WSAGetLastError();
                WSASetLastError(ol->Error);
            }
            else
                ret = NO_ERROR;
            break;
        case LSP_OP_TRANSMITPACKETS:
            lpdwFlags = &ol->TransmitPacketsArgs.dwFlags;
            lpdwBytes = NULL;
            ret = Provider->NextProcTableExt.lpfnTransmitPackets(
                    ol->ProviderSocket,
                    ol->TransmitPacketsArgs.lpPacketArray,
                    ol->TransmitPacketsArgs.nElementCount,
                    ol->TransmitPacketsArgs.nSendSize,
                   &ol->ProviderOverlapped,
                    ol->TransmitPacketsArgs.dwFlags
                    );
            if (ret == FALSE)
            {
                ret = SOCKET_ERROR;
                ol->Error = WSAGetLastError();
                WSASetLastError(ol->Error);
            }
            else
                ret = NO_ERROR;
            break;
        case LSP_OP_WSARECVMSG:
            lpdwFlags = NULL;
            lpdwBytes = &ol->WSARecvMsgArgs.dwNumberOfBytesRecvd;
            ret = Provider->NextProcTableExt.lpfnWSARecvMsg(
                    ol->ProviderSocket,
                    ol->WSARecvMsgArgs.lpMsg,
                   &ol->WSARecvMsgArgs.dwNumberOfBytesRecvd,
                   &ol->ProviderOverlapped,
                    ol->lpCallerCompletionRoutine
                    );
            if (ret == FALSE)
            {
                ret = SOCKET_ERROR;
                ol->Error = WSAGetLastError();
                WSASetLastError(ol->Error);
            }
            else
                ret = NO_ERROR;
            break;
        default:
            dbgprint("ExecuteOverlappedOperation: Unknown operation!");
            ret = SOCKET_ERROR;
            break;
    }

    err = ol->Error;

    if ((ret != NO_ERROR) && (ol->Error != WSA_IO_PENDING))
    {
        //
        // If the call immediately fails, update the OVERLAPPED info and return
        //
        ol->lpCallerOverlapped->Offset       = ol->Error;
        ol->lpCallerOverlapped->OffsetHigh   = (lpdwFlags ? *lpdwFlags : 0);
        ol->lpCallerOverlapped->InternalHigh = (lpdwBytes ? *lpdwBytes : 0);

        dbgprint("Overlap op failed immediately: %d", ol->Error);

        CheckForContextCleanup(ol);

        PutbackOverlappedStructure(ol);
    }
    else if ((ret == NO_ERROR) && (bSynchronous == FALSE))
    {
        //
        // Ideally we'd like to complete immediately here but we should wait
        // until the completion port has processed the completion packet
        // associated with this operation.
        //
        err = WSA_IO_PENDING;
        ret = SOCKET_ERROR;

        dbgprint("Succeeded without error");
    }
    else if ((ret == NO_ERROR) && (bSynchronous == TRUE))
    {
        // The winsock call actually blocked and there will be no completion
        // notification on the IOCP.
        //
        dbgprint("Succeeded without error - synchronous socket though");
    }
    else
        dbgprint("WSA_IO_PENDING");

    return ((ret == NO_ERROR) ? ret : err);
}

//
// Function: OverlappedManagerThread
//
// Description:
//    This thread receives the completion notifications for operations
//    posted to our IO completion port. Once we receive a completion
//    we'll complete the operation back to the calling app.
//
DWORD WINAPI OverlappedManagerThread(LPVOID lpParam)
{
    WSAOVERLAPPEDPLUS *lpPid = NULL;
    HANDLE             hIocp = (HANDLE)lpParam;
    ULONG_PTR          key;
    DWORD              dwBytesXfered;
    int                ret;

    while (1)
    {
        if (hIocp)
        {
            ret = GetQueuedCompletionStatus(hIocp,
                    &dwBytesXfered,
                    &key,
                    (LPOVERLAPPED *)&lpPid,
                    INFINITE);
            if ((ret == 0) || (ret == WAIT_TIMEOUT))
            {
                // Socket failures could be reported here so we still
                // call IntermediateCompletionRoutine
                dbgprint("GetQueuedCompletionStatus() failed: %d", GetLastError());
            }
            if (dwBytesXfered == -1)
            {
                // StopOverlappedManager will send a completion packet with -1
                //    bytes transfered to indicate the completion routine
                //    should exit
                dbgprint("OverlappedManagerThread: Received exit message");
                ExitThread(0);
            }

            // Handle the IO that completed
            IntermediateCompletionRoutine(WSA_IO_PENDING,
                    dwBytesXfered,
                    (OVERLAPPED *)lpPid,
                    0);
        }
        else
        {
            ret = WaitForSingleObjectEx(ghWakeupSemaphore,
                    INFINITE, 
                    TRUE);
            if ((ret == WAIT_FAILED) || (ret == WAIT_TIMEOUT))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -