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连接类相关推荐

  1. ADO.NET—数据提供程序(连接类)

    .NET Framework 数据提供程序是专门为数据处理以及快速地只进.只读访问数据而设计的组件. 一.Connection 1.介绍 开启程序和数据库之间的连结 ADO.NET底层 可自己产生对象 ...

  2. php连接电脑,PHP_深入理解php的MySQL连接类,无意间在电脑里发现还有这么 - phpStudy...

    深入理解php的MySQL连接类 无意间在电脑里发现还有这么个Mysql的连接类,也不记得哪里收藏的了,贴上来吧. 后面几个show_databases和show_tables....等方法都用了一堆 ...

  3. boost::signals2模块实现连接类测试

    boost::signals2模块实现连接类测试 实现功能 C++实现代码 实现功能 boost::signals2模块实现连接类测试 C++实现代码 #include <boost/signa ...

  4. Ado.Net 实体类、数据连接类、数据访问类

    建文件夹:定义数据连接类.数据访问类.实体类 using System; using System.Collections.Generic; using System.Linq; using Syst ...

  5. pdo mysql连接类_PHP PDO-MYSQL:如何在不同类之间使用数据库连接

    小编典典 解决方案1 替换class account_info {为class account_info extends connection { 更换 $con = new connection() ...

  6. php mysql 连接类_深入理解php的MySQL连接类

    无意间在电脑里发现还有这么个Mysql的连接类,也不记得哪里收藏的了,贴上来吧. 后面几个show_databases和show_tables....等方法都用了一堆echo,好像一直不喜欢在类的方法 ...

  7. mysql连接查询优点_1105 ROM优缺点,MySQL连接类,查插更方法

    ROM 对象关系映射,映射到数据库中的数据表 优点: 使用者不要关心SQL命令具体怎么编写 直接调用方法,来执行对应的SQL命令 缺点: 高级封装导致效率变低 会忘记SQL语句 MySQL连接类 cl ...

  8. 公共数据库访问连接类

    公共数据库访问连接类 顾名思义,公共数据库访问连接类有三个特点: 1.公共的,所以在该类中的所有方法都是静态的,因此直接调用类名即可,无须再实例化. 2.数据库访问,要访问数据库 3.连接类,所以有一 ...

  9. Python开发mysql和mongo 连接类

    因为业务需求,需要连接数据库查询数据 数据库类型:mysql,mongodb 需求:有中连机制,读取配置文件,可实例化,有日志记录 配置文件 dbconfig.conf [Mongodbtest] h ...

最新文章

  1. iOS SwiftUI篇-2 UI控件 Text Button Image List
  2. 实现BFS之“营救”
  3. 安装nvm管理多版本nodejs
  4. linux 开发组织模式,Linux内核发布模式与开发组织模式(1)
  5. infor wms 项目启动_广汽本田增城工厂No.2L WMS项目正式启动
  6. django settings 定义的变量不存在_使用Django部署机器学习模型(1)
  7. Spring Data JPA 从入门到精通~默认数据源的讲解
  8. Python 分析 10 万条弹幕告诉你:《古董局中局2》到底好不好看?
  9. 播放音乐的html语言,Html5音频和视频播放示例详解
  10. 使用Microsoft Lookback网卡解决了断网情况下 Virtual Server 虚机和主机的网络连接
  11. Proxy SwitchyOmega 使用黑名单和白名单
  12. HTC扣动板机出现射线。获得射线与VR中物体的交点并用linerender表示出来
  13. 米酷影视v7.2.1影视电影网站管理系统源码修复版
  14. 微信 原创保护开通申请协议内容
  15. android 9.0 c7Pro,三星c7pro和vivo x9哪个好?三星Galaxy c7 pro和vivo x9区别对比评测
  16. ❤️【图文并茂】Chrome浏览器(油猴子)插件安装使用教程❤️
  17. word表格边框消失怎么办_为什么我的word表格没了边框 - 卡饭网
  18. php readystate,ajax+php打造进度条 readyState各状态的简单示例
  19. 约瑟夫环问题:有n个人围成一圈,顺序编号。从第1个人开始报数(从1-3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位?
  20. debian linux 7 安装,Debian 7.0.0安装图解教程

热门文章

  1. 什么样的程序才算是好程序?
  2. 【论文泛读03】卷积LSTM网络:一种短时降雨量预测的机器学习方法
  3. ybt1271_潜水员
  4. 笔记:部署Sharding-Proxy4.1.1时遇到的坑(持续更新中。。。)
  5. Minecraft 正版
  6. 对卡尔曼滤波的系统学习
  7. oen /var/run/nginx.pid failed
  8. ZLMediaKit + wvp-GB28181-pro部署(windows64位)
  9. mysql latin1编码_mysql的latin1编码支持中文吗?
  10. MCGS如何加装透明背景位图