前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Tars-cpp源码走读——网络模块和业务模块的数据传递

Tars-cpp源码走读——网络模块和业务模块的数据传递

原创
作者头像
windealli
修改2019-01-09 09:21:43
9430
修改2019-01-09 09:21:43
举报
文章被收录于专栏:windealliwindealli

网络请求的接收

客户端的网络连接请求在下列位置进入业务处理:

代码语言:txt
复制
void TC\_EpollServer::NetThread::run() {

        ......


             case ET\_NET:
                    //网络请求
                    processNet(ev);
                    break;


        ......


}

(参考:Tars-cpp源码走读——网络模块初始化和网络连接处理)](https://cloud.tencent.com/developer/article/1377231%29%29)

通过ev.data.u32;可以取得客户端连接的socket,从而能在制定客户端连接上读写数据。

对于网络请求,processNet(ev);处理代码如下:

代码语言:txt
复制
    if(ev.events & EPOLLIN) //有数据需要读取
    {
        recv\_queue::queue\_type vRecvData;
        int ret = recvBuffer(cPtr, vRecvData);
        if(ret < 0)
        {
            delConnection(cPtr,true,EM\_CLIENT\_CLOSE);
            return;
        }
        if(!vRecvData.empty())
        {
            cPtr->insertRecvQueue(vRecvData);
        }
    }

先是通过recvBuffer从指定连接上读取数据, 然后通过cPtr->insertRecvQueue(vRecvData);把数据放在一个数据队列中,cPtr->insertRecvQueue(vRecvData);最终会通过\_handleGroup->monitor.notify();来通知真正的处理例程来处理业务逻辑。

代码语言:txt
复制
void TC\_EpollServer::BindAdapter::insertRecvQueue(const recv\_queue::queue\_type &vtRecvData, bool bPushBack)
{
    {
        if (bPushBack)
        {
            \_rbuffer.push\_back(vtRecvData);
        }
        else
        {
            \_rbuffer.push\_front(vtRecvData);
        }
    }
    TC\_ThreadLock::Lock lock(\_handleGroup->monitor);
    \_handleGroup->monitor.notify();
}

**网络数据的读取:**

代码语言:txt
复制
void TC\_EpollServer::NetThread::processNet(const epoll\_event &ev);

==>int TC\_EpollServer::NetThread::recvBuffer(TC\_EpollServer::NetThread::Connection \*cPtr, recv\_queue::queue\_type &v);

==>int TC\_EpollServer::NetThread::Connection::recv(recv\_queue::queue\_type &o)

==>int TC\_Socket::recvfrom(void \*pvBuf, size\_t iLen, struct sockaddr \*pstFromAddr, socklen\_t &iFromLen, int iFlags)

**通知handle对象**

代码语言:txt
复制
void TC\_EpollServer::NetThread::processNet(const epoll\_event &ev)

==>void TC\_EpollServer::NetThread::Connection::insertRecvQueue(recv\_queue::queue\_type &vRecvData)

==>void TC\_EpollServer::BindAdapter::insertRecvQueue(const recv\_queue::queue\_type &vtRecvData, bool bPushBack)

==>    \_handleGroup->monitor.notify();

业务模块如何等待请求到来

业务处理模块会创建一些物业处理线程,线程会阻塞在一些条件变量上,等待唤醒。

代码语言:txt
复制
void Application::main(int argc, char \*argv[])

==>void TC\_EpollServer::startHandle()

==>TC\_ThreadControl TC\_Thread::start()   //Handle 继承自TC\_Thread

==>void TC\_Thread::threadEntry(TC\_Thread \*pThread)

==>void TC\_EpollServer::Handle::run()   // Thread::run是虚函数,通过多态调用Handle::run()

void TC\_EpollServer::Handle::run()调用两个函数:

代码语言:txt
复制
void TC\_EpollServer::Handle::run()
{
    initialize();
    handleImp();
}

函数initialize();负责把用户定义的业务处理函数和handle关联起来。

函数handleImp();负责等待网络请求,以及调用处理函数。

initialize();是一个虚函数,通过多态调用void ServantHandle::initialize()

函数handleImp();中等待业务处理线程被唤醒,

代码语言:txt
复制
        {
            TC\_ThreadLock::Lock lock(\_handleGroup->monitor);
            if (allAdapterIsEmpty() && allFilterIsEmpty())
            {
                \_handleGroup->monitor.timedWait(\_iWaitTime);
            }
        }

唤醒后等待网络数据到来:

代码语言:txt
复制
bool TC\_EpollServer::BindAdapter::waitForRecvQueue(tagRecvData\* &recv, uint32\_t iWaitTime)
{
    bool bRet = false;
    bRet = \_rbuffer.pop\_front(recv, iWaitTime);
    if(!bRet)
    {
        return bRet;
    }
    return bRet;
}

在网络请求接受时,会把网络请求数据添加到_rbuffer中

至此,handle模块已经可以获取到网络请求的数据了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 网络请求的接收
  • 业务模块如何等待请求到来
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档