未获取函数指针就调用函数(如直接连接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;
}