Muduo Acceptor连接类
Acceptor连接
class Acceptor : noncopyable
{public:typedef std::function<void (int sockfd, const InetAddress&)> NewConnectionCallback;Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport);~Acceptor();void setNewConnectionCallback(const NewConnectionCallback& cb){ newConnectionCallback_ = cb; }void listen();bool listening() const { return listening_; }// Deprecated, use the correct spelling one above.// Leave the wrong spelling here in case one needs to grep it for error messages.// bool listenning() const { return listening(); }private:void handleRead();EventLoop* loop_; //主线程LoopSocket acceptSocket_; //监听连接的socketChannel acceptChannel_; //上述socket对应的ChannelNewConnectionCallback newConnectionCallback_; //accept()成功后执行的回调bool listening_; //是否开启监听连接int idleFd_; //用于处理busy-loop
};
构造函数
Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport): loop_(loop),acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),//创建一个非阻塞socket套接字acceptChannel_(loop, acceptSocket_.fd()), //创建监听连接channellistening_(false),idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC)) // 处理busy-loop
{assert(idleFd_ >= 0);acceptSocket_.setReuseAddr(true); //地址复用acceptSocket_.setReusePort(reuseport);//根据参数设置端口复用 与上面一条结合在一起取消Time_wait状态acceptSocket_.bindAddress(listenAddr); //绑定地址acceptChannel_.setReadCallback( //设置可读回调,服务器收到连接后执行的函数std::bind(&Acceptor::handleRead, this));
}
先创建了一个socket,然后用这个socket初始化acceptChannel_,并且打开了"/dev/null"被idleFd保存,但是在构造函数中并没有开始监听用户连接,这个操作被封装成为一个函数,在TcpServer::star()中调用
void Acceptor::listen()
{loop_->assertInLoopThread();listening_ = true;acceptSocket_.listen(); //启动listen() 监听连接acceptChannel_.enableReading(); //向loop中加入读事件回调 可读时调用handleRead
}
接下来看读回调
void Acceptor::handleRead()
{loop_->assertInLoopThread(); //是否在IO线程中InetAddress peerAddr; //struct sockaddr_in addr//FIXME loop until no moreint connfd = acceptSocket_.accept(&peerAddr); //peerAddr用于获取对端的协议地址if (connfd >= 0){// string hostport = peerAddr.toIpPort();// LOG_TRACE << "Accepts of " << hostport;if (newConnectionCallback_) //连接回调,在TcpServer的构造函数中设置为 TcpServer::newConnection{newConnectionCallback_(connfd, peerAddr); //把刚刚accept的cfd和addr传入}else{sockets::close(connfd);}}else //连接失败处理{LOG_SYSERR << "in Acceptor::handleRead";// Read the section named "The special problem of// accept()ing when you can't" in libev's doc.// By Marc Lehmann, author of libev.if (errno == EMFILE){::close(idleFd_);idleFd_ = ::accept(acceptSocket_.fd(), NULL, NULL);::close(idleFd_);idleFd_ = ::open("/dev/null", O_RDONLY | O_CLOEXEC);}}
}
成功获取到客端连接后生成了fd再调用回调newConnectionCallback_(),该回调在TcpServer的构造函数中被设置.
这里说下不成功的操作,也就是busy-loop,这种情况是指该进程中的文件描述被耗尽了,故而返回错误号 errno == EMFILE
那么没们在构造函数中打开的一个文件描述符就可以派上用场了,我们关闭该描述然后再次accpet(),此时就可以成功接收到
客端的连接,然后再把客端的连接关闭,再次打开"/dev/null",就可以通知客端刚刚你发起的连接失败了
Muduo Acceptor连接类相关推荐
- ADO.NET—数据提供程序(连接类)
.NET Framework 数据提供程序是专门为数据处理以及快速地只进.只读访问数据而设计的组件. 一.Connection 1.介绍 开启程序和数据库之间的连结 ADO.NET底层 可自己产生对象 ...
- php连接电脑,PHP_深入理解php的MySQL连接类,无意间在电脑里发现还有这么 - phpStudy...
深入理解php的MySQL连接类 无意间在电脑里发现还有这么个Mysql的连接类,也不记得哪里收藏的了,贴上来吧. 后面几个show_databases和show_tables....等方法都用了一堆 ...
- boost::signals2模块实现连接类测试
boost::signals2模块实现连接类测试 实现功能 C++实现代码 实现功能 boost::signals2模块实现连接类测试 C++实现代码 #include <boost/signa ...
- Ado.Net 实体类、数据连接类、数据访问类
建文件夹:定义数据连接类.数据访问类.实体类 using System; using System.Collections.Generic; using System.Linq; using Syst ...
- pdo mysql连接类_PHP PDO-MYSQL:如何在不同类之间使用数据库连接
小编典典 解决方案1 替换class account_info {为class account_info extends connection { 更换 $con = new connection() ...
- php mysql 连接类_深入理解php的MySQL连接类
无意间在电脑里发现还有这么个Mysql的连接类,也不记得哪里收藏的了,贴上来吧. 后面几个show_databases和show_tables....等方法都用了一堆echo,好像一直不喜欢在类的方法 ...
- mysql连接查询优点_1105 ROM优缺点,MySQL连接类,查插更方法
ROM 对象关系映射,映射到数据库中的数据表 优点: 使用者不要关心SQL命令具体怎么编写 直接调用方法,来执行对应的SQL命令 缺点: 高级封装导致效率变低 会忘记SQL语句 MySQL连接类 cl ...
- 公共数据库访问连接类
公共数据库访问连接类 顾名思义,公共数据库访问连接类有三个特点: 1.公共的,所以在该类中的所有方法都是静态的,因此直接调用类名即可,无须再实例化. 2.数据库访问,要访问数据库 3.连接类,所以有一 ...
- Python开发mysql和mongo 连接类
因为业务需求,需要连接数据库查询数据 数据库类型:mysql,mongodb 需求:有中连机制,读取配置文件,可实例化,有日志记录 配置文件 dbconfig.conf [Mongodbtest] h ...
最新文章
- iOS SwiftUI篇-2 UI控件 Text Button Image List
- 实现BFS之“营救”
- 安装nvm管理多版本nodejs
- linux 开发组织模式,Linux内核发布模式与开发组织模式(1)
- infor wms 项目启动_广汽本田增城工厂No.2L WMS项目正式启动
- django settings 定义的变量不存在_使用Django部署机器学习模型(1)
- Spring Data JPA 从入门到精通~默认数据源的讲解
- Python 分析 10 万条弹幕告诉你:《古董局中局2》到底好不好看?
- 播放音乐的html语言,Html5音频和视频播放示例详解
- 使用Microsoft Lookback网卡解决了断网情况下 Virtual Server 虚机和主机的网络连接
- Proxy SwitchyOmega 使用黑名单和白名单
- HTC扣动板机出现射线。获得射线与VR中物体的交点并用linerender表示出来
- 米酷影视v7.2.1影视电影网站管理系统源码修复版
- 微信 原创保护开通申请协议内容
- android 9.0 c7Pro,三星c7pro和vivo x9哪个好?三星Galaxy c7 pro和vivo x9区别对比评测
- ❤️【图文并茂】Chrome浏览器(油猴子)插件安装使用教程❤️
- word表格边框消失怎么办_为什么我的word表格没了边框 - 卡饭网
- php readystate,ajax+php打造进度条 readyState各状态的简单示例
- 约瑟夫环问题:有n个人围成一圈,顺序编号。从第1个人开始报数(从1-3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位?
- debian linux 7 安装,Debian 7.0.0安装图解教程
热门文章
- 什么样的程序才算是好程序?
- 【论文泛读03】卷积LSTM网络:一种短时降雨量预测的机器学习方法
- ybt1271_潜水员
- 笔记:部署Sharding-Proxy4.1.1时遇到的坑(持续更新中。。。)
- Minecraft 正版
- 对卡尔曼滤波的系统学习
- oen /var/run/nginx.pid failed
- ZLMediaKit + wvp-GB28181-pro部署(windows64位)
- mysql latin1编码_mysql的latin1编码支持中文吗?
- MCGS如何加装透明背景位图