使用WSAIoctl获取AcceptEx,Connectex,Getacceptexsockaddrs函数指针

转载来自:https://www.cnblogs.com/seer/p/4513959.html

未获取函数指针就调用函数(如直接连接mswsock.lib并直接调用AcceptEx)的消耗是很大的,
因为AcceptEx 实际上是存在于Winsock2结构体系之外的。
每次应用程序常试在服务提供层上(mswsock之上)调用AcceptEx时,都要先通过WSAIoctl获取该函数指针
如果要避免这个很影响性能的操作,应用程序最好是直接从服务提供层通过WSAIoctl先获取这些APIs的指针。
需要注意的是,通过WSAIoctl获取AcceptEx函数指针时,只需要传递给WSAIoctl一个有效的SOCKET即可,该Socket的类型不会影响获取的AcceptEx函数指针。
同理可以获取Connectex与GetAcceptExSockaddrs函数指针。

    void * getExtensionFunction(SOCKET s, const GUID *which_fn)
    {
        void *ptr = NULL;
        DWORD bytes=0;
        WSAIoctl(s, //标识套接字的描述符
            SIO_GET_EXTENSION_FUNCTION_POINTER,//要执行的操作的控制代码。
            (GUID*)which_fn, sizeof(*which_fn),//指向输入缓冲区的指针  //输入缓冲区的大小(以字节为单位)
            &ptr, sizeof(ptr),//指向输出缓冲区的指针。  //输出缓冲区的大小(以字节为单位)。
            &bytes, //指向实际输出字节数的指针。
            NULL, //
            NULL);//
        return ptr;
    }

    bool initExtensions()
    {
        const GUID acceptex = WSAID_ACCEPTEX;
        const GUID connectex = WSAID_CONNECTEX;
        const GUID getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS;

        SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
        if (s == INVALID_SOCKET)
            return false;

        m_pAcceptEx = (LPFN_ACCEPTEX)getExtensionFunction(s, &acceptex);
        m_pConnectEx = (LPFN_CONNECTEX)getExtensionFunction(s, &connectex);
        m_pGetAcceptExSockaddrs = (LPFN_GETACCEPTEXSOCKADDRS)getExtensionFunction(s, &getacceptexsockaddrs);
        
        closesocket(s);    

        return m_pAcceptEx!= NULL && m_pConnectEx != NULL && m_pGetAcceptExSockaddrs != NULL;
    }

 

posted @ 2021-04-13 15:17  冰糖葫芦很乖  阅读(391)  评论(0编辑  收藏  举报