在这个例子里,表示服务器与一个客户端的沟通渠道,就是一个连接,封装为类CConnect。它是当服务器接收到一个客户端连接请求之后创建的,主要用来就是管理这个连接的生命周期,以及数据的接收和发送。从生命周期上来说,当一个连接创建时就旦生了,那什么时候死亡呢?在这个类的设计上是非常优秀,非常巧妙的,因为它不会为多生存一点时间而存在,也不会提前死掉而导致非法的内存访问。有这样的特性,主要是得益于它继承类enable_shared_from_this< CConnect >,这个类enable_shared_from_this的魔力,就是为了在类内部函数使用shared_ptr,可以维护类的实例不至于失去控制,导致提前死亡。也许你会说,在类里内部直接使用shared_ptr< CConnect >(this)进行强制转换,不就是一个智能指针了吗?可是在shared_ptr这样的智能指针是不能进行强制转换,因为强制转换并不能增加类对象的生命长度。也许你会说,还有别的方法,在类里增加一个shared_ptr< CConnect >成员变量,这样可以保存起来了,就达到生命周期的延长了。但这个方案虽然可以对象生命周期变长了,但也导致对象永远删除不了,这时,你也应想起前面学习过的shared_ptr智能指针时的一大缺陷,就是不能循环地引用。因此,需要使用weak_ptr智能指针做为成员变量,这样就没有这个问题了,这就是enable_shared_from_this所实现的方案,这就是为什么要继承enable_shared_from_this的原因。这样就可以解决智能指针在类内部引用的情况,但也有一个限制的,就是不能在这个类的构造函数里使用shared_from_this(),因为在构造函数里还没有真正创建shared_ptr,这时就去使用,显然是过早了。

有了这个魔法类之后,就可让对象的生命周期从一个局部作用域里转换到另外一个地方,比如在服务器接收到连接时调用HandleAccept函数,紧跟着调用CConnect的Start函数,在这个函数就调用了shared_from_this()函数,这样就让CConnect对象在局部作用域快要结束之时,再给它增加了生命,因此CConnect对象就可以在每次收到数据或发送数据时,都可以决定是否还要继续生存下去,都是通过调用shared_from_this()函数来实现的。这样当连接出错时,不再去调用shared_from_this()函数,导致这个对象生存期到了,就自动删除,达到释放资原的目标。

从这个例子里,不但学习到网络服务器怎么样接收客户端的连接,也学习到在类成员函数里维持一个共享智能指针的生存下去的方法,这样不仅让管理内存更简单,并且让资源的利用率达到极点,完全是按需分配,不早也不迟,何乐而不为。

boost库在工作(33)网络服务端之三的更多相关文章

  1. boost库在工作(32)网络服务端之二

    在这个例子里,服务器对象主要使用boost::asio::io_service对象,这个对象主要用来构造异步接收数据使用,接着定义boost::asio::ip::tcp::acceptor对象,这个 ...

  2. boost库在工作(36)网络服务端之六

    在上面介绍了管理所有连接的类,这个类主要就是添加新的连接,或者删除不需要的连接.但是管理的类CAllConnect是没有办法知道什么时候添加,什么时候删除的,它需要从接收到连接类里获取得到新的连接,从 ...

  3. boost库在工作(37)网络UDP服务端之七

    前面介绍的都是网络TCP的服务器和客户端,其实还有UDP的服务器和客户端,同时也有同步和异步之分.UDP与TCP最大的区别,就是TCP是基于连接的,而UDP是无连接的.这里所谓的连接是指对方中断服务时 ...

  4. boost库在工作(39)网络UDP异步服务端之九

    前面创建的UDP服务器和客户端,都是同步的方式,也就是说当接收数据时,不能参与别的事情执行的.如果在一个只有界面线程的程序里,又不想创建多线程,导致复杂程度的增加,在这种情况之下,我们还有一个方案可以 ...

  5. boost库在工作(40)串行通讯

    现代的计算机技术进步很快,各种的通讯也日新月异,像USB.网络.蓝牙.WIFI等通讯技术飞速地出现,改变了整个计算机的通讯能力,速度已经达到GBit级别.但是有一种最原始的通讯方式,还是保留了30年, ...

  6. boost库在工作(15)绑定器与函数对象之三

    前面已经可以优美地解决两个参数的函数给算法for_each调用了,但是又会遇到这样的一种情况,当需要三个参数或者三个以上的参数给算法for_each调用呢?从STL里的绑定器bind1st,显然是不行 ...

  7. muduo库源码剖析(二) 服务端

    一. TcpServer类: 管理所有的TCP客户连接,TcpServer供用户直接使用,生命期由用户直接控制.用户只需设置好相应的回调函数(如消息处理messageCallback)然后TcpSer ...

  8. cocos2d-x开发:服务端基础库封装

    元旦前面几天都在忙着面试,随后的几天也就一直在做服务端基础库开发方面的工作.对于服务端开发,是很久之前的事情了.那时候我还在大学读书,一直都是在倒腾服务端开发方面的东西,毕业后参加公司工作就是一直从事 ...

  9. SimpleRpc-客户端与服务端工作模型探讨

    前言 本篇文章讲述客户端与服务端的具体设计细节.有细心的小伙伴发现,客户端和服务端的工作方式不一样:服务端是多线程计算模型,利用工作线程完成数据的读取,而客户端是单线程(利用Reactor线程完成数据 ...

随机推荐

  1. Java中抽象类和接口区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  2. 基于二叉树和数组实现限制长度的最优Huffman编码

    具体介绍详见上篇博客:基于二叉树和双向链表实现限制长度的最优Huffman编码 基于数组和基于链表的实现方式在效率上有明显区别: 编码256个符号,符号权重为1...256,限制长度为16,循环编码1 ...

  3. textarea内容有换行时存入数据库丢失问题的解决 (转载)

    http://blog.csdn.net/zhang_j_h/article/details/44563167 存入: function GetInputData(id, cmd) { var pos ...

  4. 不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针

    一直都喜欢这样显示窗口,因为简单高效: void MainWidget::ShowMyWindow() { MyWidget form(this); form.resize(,); form.exec ...

  5. OpenGL教程之新手上路

    Jeff Molofee(NeHe)的OpenGL教程- 新手上路 译者的话:NeHe的教程一共同拥有30多课,内容翔实,而且不断更新 .国内的站点实在应该向他们学习.令人吃惊的是,NeHe提供的例程 ...

  6. graph driver-device mapper-04libdevmapper基本操作

    // 创建thin pool // 调用路径:NewDeviceSet->initDevmapper->createPool 1.1 func createPool(poolName st ...

  7. ioctl、文件操作接口函数以及nand的升级模式的操作过程详解

    概述 内核中驱动文件的操作通常是通过write和read函数进行的,但是很多时候再用户空间进行的操作或许不是内核中公共代码部分提供的功能,此时就需要使用一种个性化的方法进行操作--ioctl系统调用. ...

  8. 操作系统栈溢出检測之ucosII篇

    操作系统栈溢出检測之uc/osII篇 Author               :       David Lin (林鹏) E-mail               :       linpeng1 ...

  9. Oracle Patch Bundle Update

    一.相关知识介绍 以前只知道有CPU(Critical Patch Update)和PSU(Patch Set Update),不知道还有个Bundle Patch,由于出现了TNS-12531的BU ...

  10. android优化原理

    时间换时间: 数据的异步载入 分批载入. 开机加速. 时间换空间:  分页. 空间换时间: everything.exe 音乐 图库 在开机启动后, sd卡被挂载 生成数据库. 空间换空间: 8G内存 ...