客户端的网络连接请求在下列位置进入业务处理:
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);处理代码如下:
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();
来通知真正的处理例程来处理业务逻辑。
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();
}
**网络数据的读取:**
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对象**
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();
业务处理模块会创建一些物业处理线程,线程会阻塞在一些条件变量上,等待唤醒。
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()
调用两个函数:
void TC\_EpollServer::Handle::run()
{
initialize();
handleImp();
}
函数initialize();
负责把用户定义的业务处理函数和handle关联起来。
函数handleImp();
负责等待网络请求,以及调用处理函数。
initialize();
是一个虚函数,通过多态调用void ServantHandle::initialize()
函数handleImp();
中等待业务处理线程被唤醒,
{
TC\_ThreadLock::Lock lock(\_handleGroup->monitor);
if (allAdapterIsEmpty() && allFilterIsEmpty())
{
\_handleGroup->monitor.timedWait(\_iWaitTime);
}
}
唤醒后等待网络数据到来:
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 删除。