使用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; }