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

📄 spi.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (SocketContext == NULL)
    {
        dbgprint("WSPListen: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }

    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPListen(
                SocketContext->ProviderSocket, 
                backlog, 
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPRecv
//
// Description:
//    This function receives data on a given socket and also allows for asynchronous
//    (overlapped) operation. First translate the socket handle to the lower provider
//    handle and then make the receive call. If called with overlap, post the operation
//    to our IOCP or completion routine.
//
int WSPAPI WSPRecv(
    SOCKET          s,
    LPWSABUF        lpBuffers,
    DWORD           dwBufferCount,
    LPDWORD         lpNumberOfBytesRecvd,
    LPDWORD         lpFlags,
    LPWSAOVERLAPPED lpOverlapped,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
    LPWSATHREADID   lpThreadId,
    LPINT           lpErrno)
{
    LPWSAOVERLAPPEDPLUS ProviderOverlapped;
    SOCK_INFO          *SocketContext;
    int                 ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPRecv: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }
    //
    // Check for overlapped I/O
    //
    if (lpOverlapped)
    {
        ProviderOverlapped = GetOverlappedStructure(SocketContext);
        if (!ProviderOverlapped)
        {
            UnlockSocketContext(SocketContext, lpErrno);
            dbgprint("WSPRecv: GetOverlappedStructure() returned NULL");
            *lpErrno = WSAENOBUFS;
            return SOCKET_ERROR;
        }

        ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
        CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
        ProviderOverlapped->SockInfo           = SocketContext;
        ProviderOverlapped->CallerSocket       = s;
        ProviderOverlapped->ProviderSocket     = SocketContext->ProviderSocket;
        ProviderOverlapped->Error              = NO_ERROR;
        ProviderOverlapped->Operation          = LSP_OP_RECV;
        ProviderOverlapped->lpCallerThreadId   = lpThreadId;
        ProviderOverlapped->lpCallerCompletionRoutine       = lpCompletionRoutine;
        ProviderOverlapped->RecvArgs.lpBuffers              = CopyBuffer(lpBuffers, dwBufferCount);
        ProviderOverlapped->RecvArgs.dwBufferCount          = dwBufferCount;
        ProviderOverlapped->RecvArgs.dwNumberOfBytesRecvd   = (lpNumberOfBytesRecvd ? *lpNumberOfBytesRecvd : 0);
        ProviderOverlapped->RecvArgs.dwFlags                = (lpFlags ? *lpFlags : 0);
        ProviderOverlapped->Provider = SocketContext->Provider;

        ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);

        if (ret != NO_ERROR)
        {
            *lpErrno = ret;
            ret = SOCKET_ERROR;
        }
    }
    else
    {
        SetBlockingProvider(SocketContext->Provider);
        ret = SocketContext->Provider->NextProcTable.lpWSPRecv(
                SocketContext->ProviderSocket, 
                lpBuffers, 
                dwBufferCount,
                lpNumberOfBytesRecvd, 
                lpFlags, 
                lpOverlapped, 
                lpCompletionRoutine, 
                lpThreadId,
                lpErrno);
        SetBlockingProvider(NULL);
        if (ret != SOCKET_ERROR)
        {
            SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
        }
    }

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPRecvDisconnect
//
// Description:
//    Receive data and disconnect. All we need to do is translate the socket
//    handle to the lower provider.
//
int WSPAPI WSPRecvDisconnect(
    SOCKET   s,
    LPWSABUF lpInboundDisconnectData,
    LPINT    lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPRecvDisconnect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }

    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPRecvDisconnect(
                SocketContext->ProviderSocket,                           
                lpInboundDisconnectData, 
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPRecvFrom
//
// Description:
//    This function receives data on a given socket and also allows for asynchronous
//    (overlapped) operation. First translate the socket handle to the lower provider
//    handle and then make the receive call. If called with overlap, post the operation
//    to our IOCP or completion routine.
//
int WSPAPI WSPRecvFrom(
    SOCKET          s,
    LPWSABUF        lpBuffers,
    DWORD           dwBufferCount,
    LPDWORD         lpNumberOfBytesRecvd,
    LPDWORD         lpFlags,
    struct sockaddr FAR * lpFrom,
    LPINT           lpFromLen,
    LPWSAOVERLAPPED lpOverlapped,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
    LPWSATHREADID   lpThreadId,
    LPINT           lpErrno)
{
    LPWSAOVERLAPPEDPLUS ProviderOverlapped;
    SOCK_INFO          *SocketContext;
    int                 ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPRecvFrom: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }
    //
    // Check for overlapped I/O
    //
    if (lpOverlapped)
    {
        ProviderOverlapped = GetOverlappedStructure(SocketContext);
        if (!ProviderOverlapped)
        {
            UnlockSocketContext(SocketContext, lpErrno);
            dbgprint("WSPRecvFrom: GetOverlappedStructure() returned NULL");

            *lpErrno = WSAENOBUFS;
            return SOCKET_ERROR;
        }

        ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
        CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
        ProviderOverlapped->SockInfo           = SocketContext;
        ProviderOverlapped->CallerSocket       = s;
        ProviderOverlapped->ProviderSocket     = SocketContext->ProviderSocket;
        ProviderOverlapped->Error              = NO_ERROR;
        ProviderOverlapped->Operation          = LSP_OP_RECVFROM;
        ProviderOverlapped->lpCallerThreadId   = lpThreadId;
        ProviderOverlapped->lpCallerCompletionRoutine           = lpCompletionRoutine;
        ProviderOverlapped->RecvFromArgs.lpBuffers              = CopyBuffer(lpBuffers, dwBufferCount);
        ProviderOverlapped->RecvFromArgs.dwBufferCount          = dwBufferCount;
        ProviderOverlapped->RecvFromArgs.dwNumberOfBytesRecvd   = (lpNumberOfBytesRecvd ? *lpNumberOfBytesRecvd : 0);
        ProviderOverlapped->RecvFromArgs.dwFlags                = (lpFlags ? *lpFlags : 0);
        ProviderOverlapped->RecvFromArgs.lpFrom                 = lpFrom;
        ProviderOverlapped->RecvFromArgs.lpFromLen              = lpFromLen;
        ProviderOverlapped->Provider = SocketContext->Provider;

        ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);

        if (ret != NO_ERROR)
        {
            *lpErrno = ret;
            ret = SOCKET_ERROR;
        }
    }
    else
    {
        // Make a blocking WSPRecvFrom call
        //
        SetBlockingProvider(SocketContext->Provider);
        ret = SocketContext->Provider->NextProcTable.lpWSPRecvFrom(
                SocketContext->ProviderSocket, 
                lpBuffers, 
                dwBufferCount,
                lpNumberOfBytesRecvd, 
                lpFlags, 
                lpFrom, 
                lpFromLen, 
                lpOverlapped, 
                lpCompletionRoutine, 
                lpThreadId, 
                lpErrno);
        SetBlockingProvider(NULL);
        if (ret != SOCKET_ERROR)
        {
            SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
        }
    }

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPSelect
//
// Description:
//    This function tests a set of sockets for readability, writeability, and
//    exceptions. We must translate each handle in the fd_set structures to
//    their underlying provider handles before calling the next provider's
//    WSPSelect.
//
int WSPAPI WSPSelect(
    int          nfds,
    fd_set FAR * readfds,
    fd_set FAR * writefds,
    fd_set FAR * exceptfds,
    const struct timeval FAR * timeout,
    LPINT        lpErrno)
{
    SOCK_INFO *SocketContext=NULL;
    u_int      count,
               i;
    int        HandleCount,
               ret;

    struct
    {
        SOCKET ClientSocket;
        SOCKET ProvSocket;
    } Read[FD_SETSIZE], Write[FD_SETSIZE], Except[FD_SETSIZE];

    fd_set ReadFds, WriteFds, ExceptFds;

    if ( !readfds && !writefds && !exceptfds )
    {
        *lpErrno = WSAEINVAL;
        return SOCKET_ERROR;
    }
    //
    // Translate all handles contained in the fd_set structures.
    //  For each fd_set go through and build another fd_set which contains
    //  their lower provider socket handles.
    //
    if (readfds)
    {
        FD_ZERO(&ReadFds);

        if (readfds->fd_count > FD_SETSIZE)
        {
            *lpErrno = WSAENOBUFS;
            return SOCKET_ERROR;
        }
        for (i = 0; i < readfds->fd_count; i++)
        {
            SocketContext = FindAndLockSocketContext(
                    (Read[i].ClientSocket = readfds->fd_array[i]),
                    lpErrno
                    );
            if (SocketContext == NULL)
            {
                dbgprint("WSPSelect(1): WPUQuerySocketHandleContext() failed: %d", *lpErrno);
                *lpErrno = WSAENOTSOCK;
                return SOCKET_ERROR;
            }

            Read[i].ProvSocket = SocketContext->ProviderSocket;
            FD_SET(Read[i].ProvSocket, &ReadFds);

            UnlockSocketContext(SocketContext, lpErrno);
        }
    }

    if (writefds)
    {
        FD_ZERO(&WriteFds);

        if (writefds->fd_count > FD_SETSIZE)
        {
            *lpErrno = WSAENOBUFS;
            return SOCKET_ERROR;
        }
        for (i = 0; i < writefds->fd_count; i++)
        {
            SocketContext = FindAndLockSocketContext(
                    (Write[i].ClientSocket = writefds->fd_array[i]), 
                    lpErrno
                    );
            if (SocketContext == NULL)
            {
                dbgprint("WSPSelect(2): WPUQuerySocketHandleContext() failed: %d", *lpErrno);
                *lpErrno = WSAENOTSOCK;
                return SOCKET_ERROR;
            }

            Write[i].ProvSocket = SocketContext->ProviderSocket;
            FD_SET(Write[i].ProvSocket, &WriteFds);

            UnlockSocketContext(SocketContext, lpErrno);
        }
    }

    if (exceptfds)
    {
        FD_ZERO(&ExceptFds);

        if (exceptfds->fd_count > FD_SETSIZE)
        {
            *lpErrno = WSAENOBUFS;
            return SOCKET_ERROR;
        }
        for (i = 0; i < exceptfds->fd_count; i++)
        {
            SocketContext = FindAndLockSocketContext(
                    (Except[i].ClientSocket = exceptfds->fd_array[i]), 
                    lpErrno
                    );
            if (SocketContext == NULL)
            {
                dbgprint("WSPSelect(3): WPUQuerySocketHandleContext() failed: %d", *lpErrno);
                *lpErrno = WSAENOTSOCK;
                return SOCKET_ERROR;
            }

            Except[i].ProvSocket = SocketContext->ProviderSocket;
            FD_SET(Except[i].ProvSocket, &ExceptFds);

            UnlockSocketContext(SocketContext, lpErrno);
        }
    }
    //
    // Now call the lower provider's WSPSelect with the fd_set structures we built
    //  containing the lower provider's socket handles.
    //
    if (SocketContext == NULL)
    {
        *lpErrno = WSAEINVAL;
        return SOCKET_ERROR;
    }
    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContex

⌨️ 快捷键说明

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