首页 > 代码库 > 客户端处理包方法

客户端处理包方法

不同包客户端的处理方法对于那种事件类型的连接上了,连接失败了,断开连接了bool NGP::OnConnected(){    std::lock_guard<std::mutex> lock(m_PktMutex);//加锁是因为runonce应该是另一个线程    m_queFunctions.push(std::bind(&NGP::Connect2ServerSuccess, this));//对于这种传递function,其实就跟函数指针差不多,    return true;}bool NGP::OnRec(void* pBuffer, int nSize)//这个是专门针对包的{    date_pkt pkt;    pkt.len = nSize;    pkt.date = new char[nSize];    memcpy(pkt.date, pBuffer, nSize);    {        std::lock_guard<std::mutex> lock(m_PktMutex);        m_quePktQueue.push(pkt);    }    return true;}bool NGP::OnConnectFailed(){    std::lock_guard<std::mutex> lock(m_PktMutex);    m_queFunctions.push(std::bind(&NGP::Connect2ServerFailed, this));    return true;}bool NGP::OnDisconnected()//对于这个为什么不加锁,不太明白{    m_queFunctions.push(std::bind(&NGP::Disconnected, this));    return true;}void NGP::RunOnce(){    m_spTimerFac->driveTimer();    //先检查一下其他命令    if(m_queFunctions.size())    {        for (;;)        {            std::function<void()> fun;            {                std::lock_guard<std::mutex> lock(m_PktMutex);                fun = m_queFunctions.front();            }            fun();//通过里面的函数指针直接调用            {                std::lock_guard<std::mutex> lock(m_PktMutex);                m_queFunctions.pop();            }            if(0 == m_queFunctions.size())                break;        }    }    //检查数据包,一次最少处理10个命令    for (int i = 0; i < 20; i++)    {        if (m_quePktQueue.size() == 0)            break;        date_pkt pkt;        {            std::lock_guard<std::mutex> lock(m_PktMutex);            pkt = m_quePktQueue.front();            m_quePktQueue.pop();        }        ProcessDate(pkt.date, pkt.len);        delete[] pkt.date;    }    //_TcpLink->run_one();}void NGP::ProcessDate(void* pData, int nLen){    Protocol pt = {0};    if (!pt.from_buffer(pData, nLen))//解包到pt中    {        return ;    }    auto it = m_mapPktAnalysis.find(pt.cmd_type);    if(it == m_mapPktAnalysis.end())    {        std::wstring str = L"收到未绑定解析函数的命令: ";        str += boost::lexical_cast<std::wstring>((short)pt.cmd_type);        MessageBox(NULL, str.c_str(), L"收到未知命令", MB_OK);        ::TerminateProcess(GetCurrentProcess(), 0);        //TerminateProcess终止指定进程及其所有线程。GetCurrentProcess()是个伪句柄        //只要当前进程需要一个进程句柄,就可以使用这个伪句柄。该句柄可以复制,但不可继承。不必调用CloseHandle函数来关闭这个句柄    }        it->second(pt.content, pt.size);}auto it = m_mapPktAnalysis.find(pt.cmd_type);对于这种方式服务器用的很多std::map<int, std::function<void(void* data, int len)> >    m_mapPktAnalysis;一个协议,对应一个函数指针基本都是在构造函数里面将其对应好,然后等包到的时候,根据这个map调用不同的函数这种function的用法是在本类里面绑定好,然后根据不同协议直接调用,还有一种是直接在头文件里面定义function,看看咋回事这种用法开始是在ngp里面,对于上面是调用本模块的函数,对于这种是调用别的模块的函数struct FUN{    std::function<> a;    std::function<> b;    std::function<> c;};class A{public:    A::A()    {        FUN fun;        fun.a = std::bind();        fun.b = std::bind();        fun.c = std::bind();        P->Init();    }    B* P};class B{public:    FUN m_fun;//项目里面作为成员变量    Init(FUN& fun)//实现调用初始化函数    {        m_fun = fun;    }};看来function的两种用法就是这样了NGP就是根据发过来的协议(包),事件调用客户端绑定好的函数

 

客户端处理包方法