LPFN_DISCONNECTEX Get_DisconnectEx_FuncPtr (SOCKET sock) { GUID guid = WSAID_DISCONNECTEX; return (LPFN_DISCONNECTEX)GetExtensionFuncPtr(sock, guid); }
LPFN_TRANSMITFILE Get_TransmitFile_FuncPtr(SOCKET sock) { GUID guid = WSAID_TRANSMITFILE; return (LPFN_TRANSMITFILE)GetExtensionFuncPtr(sock, guid); }
LPFN_GETACCEPTEXSOCKADDRS Get_GetAcceptExSockaddrs_FuncPtr(SOCKET sock) { GUID guid = WSAID_GETACCEPTEXSOCKADDRS; return (LPFN_GETACCEPTEXSOCKADDRS)GetExtensionFuncPtr(sock, guid); }
LPFN_ACCEPTEX Get_AcceptEx_FuncPtr(SOCKET sock) { GUID guid = WSAID_ACCEPTEX; return (LPFN_ACCEPTEX)GetExtensionFuncPtr(sock, guid); }
LPFN_CONNECTEX Get_ConnectEx_FuncPtr(SOCKET sock) { GUID guid = WSAID_CONNECTEX; //Connectex return (LPFN_CONNECTEX)GetExtensionFuncPtr(sock, guid); }
void main() { // 创建监听套节字,绑定到本地端口,进入监听模式 int nPort = 4567; SOCKET sListen = ::WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, //此三个参数与标准socket相同 NULL, //指定下层服务提供者,可以是NULL 0, //保留 WSA_FLAG_OVERLAPPED); //指定socket属性,要使用重叠I/O模型,必须指定WSA_FLAG_OVERLAPPED //如果使用socket则默认指定WSA_FLAG_OVERLAPPED //绑定并监听IP和端口 SOCKADDR_IN si; si.sin_family = AF_INET; si.sin_port = ::ntohs(nPort); si.sin_addr.S_un.S_addr = INADDR_ANY; ::bind(sListen, (sockaddr*)&si, sizeof(si)); ::listen(sListen, 200); // 为监听套节字创建一个SOCKET_OBJ对象 GetSocketObj函数仅仅开辟一个PSOCKET_OBJ内存并将套接字传入, PSOCKET_OBJ pListen = GetSocketObj(sListen); // 加载扩展函数AcceptEx GUID GuidAcceptEx = WSAID_ACCEPTEX; DWORD dwBytes; //套接字选项和I/O控制命令 此处用来获取AcceptEx函数指针 WSAIoctl(pListen->s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &pListen->lpfnAcceptEx, sizeof(pListen->lpfnAcceptEx), &dwBytes, NULL, NULL); g_pfnGetAcceptExSockaddrs = (LPFN_GETACCEPTEXSOCKADDRS)GetExtensionFuncPtr(pListen->s); // 创建用来重新建立g_events数组的事件对象 g_events[0] = ::WSACreateEvent(); // 在此可以投递多个接受I/O请求 投递5个接受连接请求 for(int i=0; i<5; i++) { PostAccept(GetBufferObj(pListen, BUFFER_SIZE)); } ::WSASetEvent(g_events[0]); while(TRUE) { int nIndex = ::WSAWaitForMultipleEvents(g_nBufferCount + 1, g_events, FALSE, WSA_INFINITE, FALSE); if(nIndex == WSA_WAIT_FAILED) { printf("WSAWaitForMultipleEvents() failed \n"); break; } nIndex = nIndex - WSA_WAIT_EVENT_0; for(int i=0; i<=nIndex; i++) { int nRet = ::WSAWaitForMultipleEvents(1, &g_events[i], TRUE, 0, FALSE); if(nRet == WSA_WAIT_TIMEOUT) continue; else { ::WSAResetEvent(g_events[i]); // 重新建立g_events数组 if(i == 0) { RebuildArray(); continue; } // 处理这个I/O PBUFFER_OBJ pBuffer = FindBufferObj(g_events[i]); if(pBuffer != NULL) { if(!HandleIO(pBuffer)) RebuildArray(); } } } } }