muduo网络库源码解析 五
来源:互联网 发布:亚瑟士t4c1n4993 知乎 编辑:程序博客网 时间:2024/05/16 01:46
TcpConnection用来管理连接,包括连接的状态、消息的处理(发、收),该类是muduo中唯一一个实用shared_ptr来进行管理的类,也是唯一继承enable_shared_from_this的类,这源于TcpConnection类的模糊的生命期。在本章的结尾我们会进行分析。
我们首先来分析一下私有成员:
enum StateE { kConnecting, kConnected, kDisconnected}; //连接的状态void setState(StateE s) { state_ = s; } //设置状态//处理读、写、关闭、错误事件void handleRead();void handleWrite();void handleClose();void handleError();EventLoop *loop_; //记录所属的EventLoopstd::string name_; //记录连接的名称StateE state_; //记录连接的状态std::unique_ptr<Socket> socket_; //不明所以,暂且认为记录文件描述符fdstd::unique_ptr<Channel> channel_; //管理fd,设置各种类型的回调,并加入poller队列InetAddress localAddr_; //记录本地地址InetAddress peerAddr_; //记录对端地址ConnectionCallback connectionCallback_; //连接回调函数MessageCallback messageCallback_; //消息到来回调函数CloseCallback closeCallback_; //关闭回调构造函数如下:
TcpConnection::TcpConnection(EventLoop *loop, const std::string name,int sockfd, const InetAddress &localAddr, const InetAddress &peerAddr):loop_(loop),name_(name),socket_(new Socket(sockfd)),localAddr_(localAddr),peerAddr_(peerAddr),channel_(new Channel(loop_, socket_->fd())),state_(kConnecting){std::cout << "TcpConnection::ctor[" << name_ << "] at " << this<< " fd=" << sockfd<<"\n";channel_->setReadCallback(std::bind(&TcpConnection::handleRead, this));channel_->setCloseCallback(std::bind(&TcpConnection::handleClose, this));/*channel_->setErrorCallback(std::bind(&TcpConnection::handleError, this));*/}除了对成员进行初始化外,在Channel中设置了读、写(当前代码没有加上)、关闭、错误回调函数。
另外还有两个重要的public成员函数:
void connectEstablished();void connectDestroyed();一个是连接建立,一个是连接销毁,定义如下:
void TcpConnection::connectEstablished(){loop_->assertInLoopThread();setState(kConnected);channel_->enableReading();connectionCallback_(shared_from_this());}void TcpConnection::connectDestroyed(){loop_->assertInLoopThread();setState(kDisconnected);channel_->disableAll();loop_->removeChannel(channel_.get());}连接建立,首先设置状态为kConnected,接着调用channel的enableReading,将connfd加入poller队列,最后调用connectionCallback_回调,注意,这里用的是shared_from_this()。
连接销毁,同样,首先设置状态为kDisconnected,然后调用channel的disableAll,将connfd从polle队列中删除,最后调用loop的removeChannel将channel删除
这两个函数供上层调用,即TcpServer调用。
下面我们来分析一下TcpConnection的生命期。首先TcpConnectionPtr是一个智能指针类型——shared_ptr,TcpConnection首次创建是在TcpServer::newConnection函数中
TcpConnectionPtr conn(new TcpConnection(loop_, connName, sockfd, localAddr, peerAddr));此时,引用计数为1,而后为了管理,conn被放入connections_(是一个map)中,引用计数为2。又由于onConnection和onMessage都是传入的shared_from_this(),所以引用计数都会增加。TcpServer::newConnection结束后,引用计数会减1。就是说,如果没有调用回调函数,那么conn的引用计数最终为1,即存在于connections_中。那么什么时候引用计数为0,conn被析构呢?上层TcpServer调用removeConnection,该函数会接受一个conn的引用,会增加引用计数,接着调用connections_删除map中的conn,引用计数减1,接着调用conn的connectionDestroy,处理与conn相关的channel,当次函数结束的时候,引用计数减为0(如果此时没有调用messageCallback或者其它回调的话),conn会被析构。
我们开始的时候提到,用shared_ptr来管理TcpConnection,是因为TcpConnection的生命期比较模糊。在完整的muduo中,主线程只负责接受连接,然后在TcpConnection::newConnection中启动一个线程,把TcpConnection放入该线程处理。conn的各种事件都在新的线程中处理。比如当conn正在处理一个request,此时线程是“阻塞”在这个处理上的,客户端这时候断开连接,线程的EventLoop会收到close事件,但是此时线程“阻塞”在处理request中,并不能马上处理close事件,只有当request结束后,才会处理close事件。所以,对服务器端来说,只有当conn不在被使用且客户端断开连接的时候,conn才会被析构。书上说使用shared_ptr管理连接,可以防止串话。
关于TcpConnection生命期分析的不知道对不对,如果有不正确的地方,见谅。
- muduo网络库源码解析 五
- muduo网络库源码解析 一
- muduo网络库源码解析 二
- muduo网络库源码解析 三
- muduo网络库源码解析 四
- muduo网络库源码解析 六
- muduo网络库源码解析 七
- Muduo网络库源码分析(五)Acceptor和TcpServer类
- muduo网络库源码分析-定时器
- muduo源码解析之TcpConnection
- muduo源码解析之EventLoopThread
- Muduo之Channel源码解析
- muduo网络库之net库源码分析(1)
- muduo库源码解析:单例模式singleton
- muduo网络库源码学习————互斥锁
- Muduo 网络库源码分析 之 关键技术点总结
- Muduo 网络库源码分析 之 关键技术点总结
- muduo网络库源码阅读Step by Step
- python使用tkinter写带界面的工具
- python使用pyqt写带界面工具
- 基于pyteseract google ocr的图形验证码识别
- 51NOD 1276 岛屿的数量(脑洞+思维)
- 一个网址
- muduo网络库源码解析 五
- python2.7中关于编码,json格式的中文输出显示
- 怎么制作免费短信轰炸机
- Professional JS(4.1.3-Arguments passing---end)
- 关于无效验证码
- 介绍requests+threading多线程爬虫,提取采用xpath 和正则两种,介绍线程锁
- HTML5动画-翻转音乐盒效果动画
- web开发中的安全问题
- 单线程、多线程、多进程、协程比较,以爬取新浪军事历史为例