GS给客户单发包以及m_queGcWait(所有GC共享)

GS给客户单发包以及m_queGcWait(所有GC共享)
send_stat BaseChannel::SendCmd(int nCmd, void* pData, int nLen)
{
    Protocol Ptl;
    Ptl.cmd_type    = nCmd;
    Ptl.content        = pData;
    Ptl.size        = nLen;
    void* tmpBuffer = ms_pSendBuff2C;

    if (nLen > __GC_MAX_SEND_BUFF_LEN)
    {
        ShuiHu::GetLogger()->Fatal( "【%s(%d行)】严重错误,发送cmd=%d包,包长度(%d)比最大发送包(%d)更大 ",
            __FUNCTION__, __LINE__, nCmd, nLen, __GC_MAX_SEND_BUFF_LEN);
        safe::error_msg("GC发送包长度过长!");
    }

    int nSize = Ptl.to_buffer(tmpBuffer, __GC_MAX_SEND_BUFF_LEN);//打包到tmpBuffer
    if(-1 == nSize)
        return send_stat::send_parameter_error;

    DataPkt Pkt;
    //此处用内存池有个问题,加入共享内存一直pop不出来,这个内存迟早会用完,有个缓冲队列好好处是没发送出去你可以返回去干其他的事情,等下次去发送
    //所以此处需要重新分配内存去保存包内容,内存池的好处就是重复的new,delete
    //我看了下他这个pop如果用完了他是重新new的,这还差不多,不然要等待扯犊子了
    Pkt.pData = m_pShare->PopPkt(nSize);//GC共享内存池中分配一块内存
    Pkt.nSize = nSize;
    memcpy(Pkt.pData, tmpBuffer, nSize);

    m_queCmd.push(Pkt);//发到命令缓冲中

    return SendCmdTry();
}

send_stat BaseChannel::SendCmdTry()//只能这样说每个GC每发送一个包,他都企图把它所有剩余的包发送出去
{
    if (!m_queCmd.size())
        return send_stat::send_succeed;

    for(;;)
    {
        if (m_queCmd.empty())
            break;
        DataPkt pkt = m_queCmd.front();

        {
            send_stat hr = m_pDataLayer->SendData(m_nChannelId, pkt.pData, pkt.nSize);//发给网络层
            if(hr != send_stat::send_succeed)//没发送成功,说明发送端的共享内存用完了(有个疑问为什么不把共享内存弄大一点)
            {
                //放入等待队列,让GS来发送(有个问题为什么要让GS发送,发送失败直接返回,下次再发送就是了)
                m_pShare->PushGcWait(m_nChannelId);//将其放到未发送的所有GC共享队列中去
                return hr;
            }
        }

        m_queCmd.pop();//说明发送成功

        m_pShare->PushPkt(pkt.pData, pkt.nSize);//归还共享内存
    }
    return send_stat::send_succeed;
}
时间: 2024-10-07 07:24:06

GS给客户单发包以及m_queGcWait(所有GC共享)的相关文章

一个简单的客户单与服务端程序

实验环境是linux系统,效果如下: 1.启动服务端程序,监听在6666端口上  2.启动客户端,与服务端建立TCP连接  3.建立完TCP连接,在客户端上向服务端发送消息 4.断开连接 实现的功能很简单,但是对于初来乍到的我费了不少劲,因此在此总结一下,如有错点请各位大神指点指点 什么是SOCKET(插口): 这里不用 "套接字" 而是用 "插口" 是因为在<TCP/IP协议卷二>中,翻译时也是用 "插口" 来表示socket的.

科普:客户关系管理系统对客户信息管理的6大帮助

每次展会企业都会收集到很多客户信息,再加上之前的老客户信息,可以说,客户信息千千万,那么,怎么管理呢,同时,又怎样在数以万计的客户信息中,找到目标客户的信息呢,这些都是企业所关心的客户信息管理问题,而这些,客户关系管理系统就可以帮助企业轻松解决. 1.客户信息的多种录入方式 说到客户信息,首当其冲的就是客户信息的保存问题,企业展会的客户资源,企业原有的客户资源,员工自己开发的客户资源,这么多客户信息的整理确实是个难题:但是在客户关系管理系统内,就简单多了,比如智邦国际客户关系管理系统内,企业就可

浅析http请求头常见的表单文件上传

首先先了解下application/x-www-form-urlencoded和multipart/form-data的区别 application/x-www-form-urlencoded: 是常用的表单发包方式,普通的表单提交,或者js发包,默认都是通过这种方式, <form enctype="application/x-www-form-urlencoded" action="http://" method="POST"> &

使用 Zend_Form_Element 生成表单元素 --(手册)

表单由元素组成,它一般对应于 HTML 表单输入.Zend_Form_Element 封装了单个表单元素,并完成下列工作: 校验(提交的数据有效乎?) 抓取校验错误代码和消息 过滤(在校验和/或输出之前元素如何转义或规范化?) 解析(元素如何显示?) 元数据和属性(什么信息进一步修饰元素?) 基础类 Zend_Form_Element 对许多类有合理的缺省设置,但最好还是继承这个类来完成特殊意图的元素.另外,Zend Framework 带有许多标准的 XHTML 元素. 1.  插件加载器 Z

【Scala】单例对象与伴生对象

Scala的单例对象 Scala不能定义静态成员,而是代之定义单例对象(singleton object).以object关键字定义. 对象定义了某个类的单个实例,包含了你想要的特性: object Accounts{ private var lastNumber = 0 def newUniqueNumber() = { lastNumber += 1; lastNumber} } 当你在应用程序中需要一个新的唯一账号时,调用Account.newUniqueNumber()即可. 对象的构造

数据持久化、单例、重载【添加对不可访问的成员的操作】、魔术方法、类常量、static关键字对self的补充【静态延迟绑定实现$this的效果】、参数类型约束【参数前加类名】、遍历【iterator接口】、快速排序

1.数据持久化过程[传输(例如表单提交或php交互mysql)和保存过程] 使用的是字符串形式的流数据. 数据流就是为了传输[按照序列的形式进行传输] [http://baike.baidu.com/link?url=0MtUQMhFzc_EwJc09rXZV8KlfOL4jis6XNbRfmGA3rQhDcGwOp8togLVQjXBV34M] 所以将其他类型数据转化为字符串的过程也是序列化的过程 [这个概念和图片.视频的流媒体的区别?] [注意点] 另外mysql中sql语句中的某些关键词为

转:【Scala】单例对象与伴生对象

转自:http://blog.csdn.net/jasonding1354/article/details/46507595 Scala的单例对象 Scala不能定义静态成员,而是代之定义单例对象(singleton object).以object关键字定义. 对象定义了某个类的单个实例,包含了你想要的特性: object Accounts{ private var lastNumber = 0 def newUniqueNumber() = { lastNumber += 1; lastNum

scala 单例、伴生对象、伴生类

单例:使得对象成为系统中的唯一实例 package scala object single { private var sno:Int = 3; def singlesno()={ sno += 1 sno } } object singleTest { def main(args: Array[String]): Unit = { println(single.singlesno()) println(single.singlesno()) } } 伴生对象: 当单例对象与某个类共享同一个名称

Spring工作原理与单例

最近看到spring管理的bean为单例的,当它与web容器整合的时候始终搞不太清除,就网上搜索写资料, Tomcat与多线程, servlet是多线程执行的,多线程是容器提供的能力. servlet为了能并发执行, 是因为servlet被这些thread使用,tomcat里创建响应的socketServer线程类接收请求连接,然后在再创建或引用对应的servlet实例来处理请求连接.servlet是单例的,只创建一次.所以最好不要使用serlvet中的实例字段. spring中的bean对象默