请选择 进入手机版 | 继续访问电脑版

赵耀的知识库

 找回密码
 立即注册
搜索
热搜: 报盘 状态 失败
查看: 4890|回复: 0

数据发送原理

[复制链接]

421

主题

428

帖子

2622

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2622
发表于 2021-5-20 09:57:12 | 显示全部楼层 |阅读模式
每个线程都在做相同的事,就是死循环检测预期事件:void CEventDispatcher::Run()
{
        while(m_bShouldRun)
        {
                DispatchIOs();               
                SyncTime();
                CheckTimer();
                DispatchEvents();
        }
}

而发送事件就在如下代码:
void CSelectReactor::DispatchIO(fd_set &readfds,fd_set  &writefds, int &MaxID)
{
        CEventHandlerList::iterator itor=m_IOList.begin();
        for(; itor != m_IOList.end(); itor++){
                if((*itor)==NULL){
                        continue;        //事件处理对象可能已被删除
                }
               
                int nReadID, nWriteID;
                ((CEventHandler *)(*itor))->GetIds(&nReadID, &nWriteID);
               
                if(nReadID<0 || (nReadID>0 && FD_ISSET(nReadID,&readfds)))
                {
                        ((CEventHandler *)(*itor))->HandleInput();
                }
               
                if((*itor)==NULL){
                        continue;        //事件处理对象可能已被删除
                }
               
                if(nWriteID<0 || (nWriteID>0 && FD_ISSET(nWriteID, &writefds)))
                {
                        ((CEventHandler *)(*itor))->HandleOutput();
                }
        }
}

其中:HandleOutput就是发送事件检测。
死循环检测,一旦缓冲区有数据,就会发送出去。
所以上层协议所要做的是把数据放到缓冲区,下层协议负责把缓冲区的数据发送出去。
tcp协议中发送数据代码:
int CChannelProtocol::HandleOutput()
{
         return Flush();
}
int CChannelProtocol::Flush()
{
        if (!m_pChannel->CheckConnection())
        {
                return 0;
        }

        for(int i=0; i<8; i++)
        {
                int nDataLen = 8192;                //--可能需要调整
               
                char *pData=(char *)m_CacheList.GetData(nDataLen);               
                if(pData==NULL)
                {
                        break;
                }
                int len = m_pChannel->Write(nDataLen, pData);
                if(len < 0){
                        NotifyError(MSG_CHNLERR_WRITE, 0, this);
                        return len;
                }

                m_CacheList.PopFront(len);
                                
                if(len != nDataLen)
                {
                        break;
                }
        }
        return 0;
}

发送是其中的Write函数完成,调用底层tcp的send函数发送。

发送数据的另外一个位置代码:
int CChannelProtocol::Push(CPackage *pPackage, CProtocol *pUpper)
{
        if (m_pChannel->GetType() == CT_STREAM)
        {
                m_CacheList.PushBack(pPackage->Address(),pPackage->Length());
                return 0;
        }
        else
        {
                int len=m_pChannel->Write(pPackage->Length(),pPackage->Address());
                if (len != pPackage->Length())
                {
                        return -1;
                }
        }
        return 0;
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则