客户端处理包方法

不同包客户端的处理方法
对于那种事件类型的
连接上了,连接失败了,断开连接了
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就是根据发过来的协议(包),事件调用客户端绑定好的函数

 

posted @ 2014-11-15 01:34  zzyoucan  阅读(192)  评论(0编辑  收藏  举报