未获取函数指针就调用函数(如直接连接mswsock..lib并直接调用AcceptEx)的消耗是很大的,因为AcceptEx 实际上是存在于Winsock2结构体系之外的。每次应用程序常试在服务提供层上(mswsock之上)调用AcceptEx时,都要先通过WSAIoctl获取该函数指针。如果要避免这个很影响性能的操作,应用程序最好是直接从服务提供层通过WSAIoctl先获取这些APIs的指针。
奇迹世界 network 类里面就进行指针获取
void MsWinsockUtil::LoadExtensionFunction( SOCKET ActiveSocket )
{
//AcceptEx 窃荐 啊廉坷扁 (dll俊辑..)
GUID acceptex_guid = WSAID_ACCEPTEX;
LoadExtensionFunction( ActiveSocket, acceptex_guid, (void**) &m_lpfnAccepteEx);  
//TransmitFile 窃荐 啊廉坷扁 (dll俊辑..)
GUID transmitfile_guid = WSAID_TRANSMITFILE;
LoadExtensionFunction( ActiveSocket, transmitfile_guid, (void**) &m_lpfnTransmitFile);  
//GetAcceptExSockaddrs 窃荐 啊廉坷扁
GUID guidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
LoadExtensionFunction( ActiveSocket, guidGetAcceptExSockaddrs, (void**) &m_lpfnGetAcceptExSockAddrs);  
//DisconnectEx 窃荐 啊廉坷扁
GUID guidDisconnectEx = WSAID_DISCONNECTEX;
LoadExtensionFunction( ActiveSocket, guidDisconnectEx, (void**) &m_lpfnDisconnectEx );
}  
bool MsWinsockUtil::LoadExtensionFunction( SOCKET ActiveSocket, GUID FunctionID, void **ppFunc )
{
DWORD dwBytes = 0;  
if (0 != WSAIoctl(
   ActiveSocket, 
   SIO_GET_EXTENSION_FUNCTION_POINTER,
   &FunctionID,
   sizeof(GUID),
   ppFunc,
   sizeof(void *),
   &dwBytes,
   0,
   0))
{
   return false;
}  
return true;
}  
LPFN_ACCEPTEX     MsWinsockUtil::m_lpfnAccepteEx     = NULL;
LPFN_TRANSMITFILE    MsWinsockUtil::m_lpfnTransmitFile    = NULL;
LPFN_GETACCEPTEXSOCKADDRS MsWinsockUtil::m_lpfnGetAcceptExSockAddrs = NULL;
LPFN_DISCONNECTEX    MsWinsockUtil::m_lpfnDisconnectEx    = NULL;  
收包和发包循环:
服务器需要进行的连接如下:
1、 与其他服务器连接
2、监听绑定端口
这个2个内容都封装进SESSION内里面,通过NETWORKOBJECT对象判断该进行哪部分的包处理
if( !pIOCPServer->Init( &desc, 1 ) )
根据参数&desc ,对完成端口进行设置  
内容有:创建 io_thread(工作者线程), accept_thread(绑定端口),connect_thread(连接其他服务器), send_thread(收包线程),并根据连接的最大数目分配好session pool。
if( !pIOCPServer->StartListen( CLIENT_IOHANDLER_KEY, “127.0.0.1”, 6000 ) )
{
   printf( “监听出错” );
   return 0;
}  
pIOCPServer->Connect( CLIENT_IOHANDLER_KEY, pNetObj, “127.0.0.1”, 7000 );
收包:
pIOCPServer->Update() ———》 IOHANDLER_MAP_ITER it->second->Update() ———-》
VOID IoHandler::Update()
{
ProcessActiveSessionList();  
if( !m_pAcceptedSessionList->empty() )
{
   ProcessAcceptedSessionList();
}  
if( !m_pConnectSuccessList->empty() )
{
   ProcessConnectSuccessList();
}  
if( !m_pConnectFailList->empty() )
{
   ProcessConnectFailList();
}  
KickDeadSessions();
}    
收包循环
    if( !pSession->ProcessRecvdPacket( m_dwMaxPacketSize ) )
    {
     pSession->Remove();
    }  
发包循环
unsigned __stdcall send_thread( LPVOID param )
{
IOCPServer *pIOCPServer = (IOCPServer*)param;
IOHANDLER_MAP_ITER it;
while( !pIOCPServer->m_bShutdown )
{
   Sleep( 10 );  
   for( it = pIOCPServer->m_mapIoHandlers.begin(); it != pIOCPServer->m_mapIoHandlers.end(); ++it )
   {
    it->second->ProcessSend();
   }
}  
return 0;
}
我最擅长从零开始创造世界,所以从来不怕失败,它最多也就让我一无所有。

