zoukankan      html  css  js  c++  java
  • 客户端处理包方法

    不同包客户端的处理方法
    对于那种事件类型的
    连接上了,连接失败了,断开连接了
    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就是根据发过来的协议(包),事件调用客户端绑定好的函数
  • 相关阅读:
    Linux中的用户和用户组
    GCC编译过程
    C++设计模式——单例模式(转)
    快速排序之python
    归并排序之python
    计数排序之python
    希尔排序之python
    插入排序之python
    选择排序之python
    冒泡排序之python
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4098627.html
Copyright © 2011-2022 走看看