• 奇迹世界服务器架构(4)


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

  • 相关阅读:
    Daily Scrum 10.29
    Daily Scrum 10.28
    git第一次commit代码阅读
    软工课程项目-数据库管理
    [Go]字典(map)的操作和约束
    [Go]链表的相关知识
    Kubernetes网络设计原则
    [Go]程序实体
    [Kubernetes]集群配置免密登录Permission denied (publickey,password) 解决办法
    [Go]GOPATH相关知识点
  • 原文地址:https://www.cnblogs.com/flying_bat/p/1366590.html
Copyright © 2020-2023  润新知