Example #1
0
void NetSystem::CompleteRecv(epoll_event& event) {
    LinkInfo * pLink = (LinkInfo *) event.data.ptr;
    //如果是已经连接的用户,并且收到数据,那么进行读入。
    char recvbuff[RECVBUF_SIZE];
    memset(recvbuff, 0, RECVBUF_SIZE);
    int nRecvLen = 0;
    //在这里会不会出现因为tpc接受缓冲区一直有东西存在 所以就直卡死在这个read中 所以改成read一次
    //但是有可能出现消息丢失
    while (true) { //这里注意 要增加 频率检测
        if ((nRecvLen = read(pLink->m_socket, recvbuff, RECVBUF_SIZE)) <= 0) {
            if (EAGAIN == errno && -1 == nRecvLen) {
                break;
            }

            if (0 == nRecvLen) {
                LOG_ERROR("NetSystem::MainLoop client is EOF, LinkID : %d", pLink->m_socket);
                m_pCallBackSystem->ExKernelEvent(m_pKernel,
                        pLink->m_remotetype, KERNEL_EVENT_CONNECTION_EOF, pLink->m_socket, VarList());
            } else {
                LOG_ERROR("NetSystem::MainLoop client is break off, LinkID : %d", pLink->m_socket);
                m_pCallBackSystem->ExKernelEvent(m_pKernel,
                        pLink->m_remotetype, KERNEL_EVENT_CONNECTION_BREAK, pLink->m_socket, VarList());
            }

            CleanLink(pLink);
            event.data.ptr = NULL;
            break;
        }

        if (!pLink->m_recvstream.WriteBuff(recvbuff, nRecvLen)) {
            LOG_TRACE("NetSystem::MainLoop WriteBuff error, LinkID : %d", pLink->m_socket);
            m_pCallBackSystem->ExKernelEvent(m_pKernel,
                    pLink->m_remotetype, KERNEL_EVENT_CONNECTION_BREAK, pLink->m_socket, VarList());
            CleanLink(pLink);
            event.data.ptr = NULL;
            break;
        }

        Archive msg;
        VarList args;
        while (pLink->m_recvstream.ReadArchive(msg)) {
            if (msg.ToVarList(args)) {
                if (args.Type(0) != TYPE_INT) {
                    LOG_ERROR("NetSystem::MainLoop Error msg");
                    m_pCallBackSystem->ExKernelEvent(m_pKernel,
                            pLink->m_remotetype, KERNEL_EVENT_CONNECTION_BREAK, pLink->m_socket, VarList());
                    CleanLink(pLink);
                    event.data.ptr = NULL;
                    break;
                }

                UI32 nMsgId = args.GetInt(0);
                m_pCallBackSystem->ExMsgCall(m_pKernel, pLink->m_remotetype, nMsgId, pLink->m_socket, args);

                const CIdentity player = m_pObjectManage->QueryPlayer(pLink->m_socket);
                if (player != CIdentity_INIT()) {
                    m_pCallBackSystem->ExMsgCall(m_pKernel, pLink->m_remotetype, nMsgId, player, args);
                }
            }
        }
    }

    if (pLink != NULL) {
        //设置用于写操作的文件描述符
        struct epoll_event ev;
        ev.data.ptr = pLink;
        ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
        epoll_ctl(m_epfd, EPOLL_CTL_MOD, pLink->m_socket, &ev);
    }

    return;
}