muduo源码剖析之Acceptor监听类
简介
Acceptor类用于创建套接字,设置套接字选项,调用socket()->bind()->listen()->accept()函数,接受连接,然后调用TcpServer设置的connect事件的回调。
listen()//在TcpServer::start中调用
封装了一个listen fd相关的操作,用于mainLoop
成员及属性解析
Acceptor - 逻辑上的内部类
接受器封装,实质上就是对Channel的多一层封装
主要接口
listen
监听连接
当新连接进入时,调用Socket::accept创建套接字,触发TcpServer的回调
setNewConnectionCallback
TcpServer通过该接口设置回调,当新连接套接字创建后,创建TcpConnection对象
核心实现:
通过socket::accept接受新连接,获得套接字fd
这个fd作为参数调用TcpServer注册的回调
主要成员
- loop
- channel
- idlefd
非常巧妙的设计,在服务器压力过大,无法新建文件描述符时,通过这个idlefd拒绝连接
来自libevent的设计
源码剖析
Acceptor.h
#ifndef MUDUO_NET_ACCEPTOR_H
#define MUDUO_NET_ACCEPTOR_H#include <functional>#include "muduo/net/Channel.h"
#include "muduo/net/Socket.h"namespace muduo
{
namespace net
{
class EventLoop;
class InetAddress;///
/// Acceptor of incoming TCP connections.
///
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_;Socket acceptSocket_;Channel acceptChannel_;NewConnectionCallback newConnectionCallback_;bool listening_;int idleFd_;
};} // namespace net
} // namespace muduo#endif // MUDUO_NET_ACCEPTOR_H
Acceptor.cc
// Copyright 2010, Shuo Chen. All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)#include "muduo/net/Acceptor.h"#include "muduo/base/Logging.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include "muduo/net/SocketsOps.h"#include <errno.h>
#include <fcntl.h>
//#include <sys/types.h>
//#include <sys/stat.h>
#include <unistd.h>using namespace muduo;
using namespace muduo::net;Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport): loop_(loop),acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),//创建一个非阻塞的socket fdacceptChannel_(loop, acceptSocket_.fd()),//创建socket fd的channellistening_(false),//是否处于监听状态idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC))
{assert(idleFd_ >= 0);acceptSocket_.setReuseAddr(true); //设置ip地址复用acceptSocket_.setReusePort(reuseport); //设置端口复用acceptSocket_.bindAddress(listenAddr); //bind()函数封装,绑定ip和端口acceptChannel_.setReadCallback(std::bind(&Acceptor::handleRead, this));//设置accept的回调函数
}Acceptor::~Acceptor()
{acceptChannel_.disableAll();//将mainloop poller监听集合中移除,取消所有事件的监听acceptChannel_.remove();//在events_删除channel::close(idleFd_);//关闭文件
}void Acceptor::listen()//开始监听fd
{loop_->assertInLoopThread();//判断是不是和创建时的io线程处于同一个线程listening_ = true;//是否监听acceptSocket_.listen();//真正的监听函数acceptChannel_.enableReading();//设置监听读事件
}void Acceptor::handleRead()//当有client connnect时,则会调用
{loop_->assertInLoopThread();InetAddress peerAddr;//FIXME loop until no moreint connfd = acceptSocket_.accept(&peerAddr);//接收client connect,返回值==accept()返回值if (connfd >= 0){// string hostport = peerAddr.toIpPort();// LOG_TRACE << "Accepts of " << hostport;if (newConnectionCallback_)//如果设置了connect cb,则调用,否则则关闭这个连接{newConnectionCallback_(connfd, peerAddr);}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);}}
}
相关文章:
muduo源码剖析之Acceptor监听类
简介 Acceptor类用于创建套接字,设置套接字选项,调用socket()->bind()->listen()->accept()函数,接受连接,然后调用TcpServer设置的connect事件的回调。 listen()//在TcpServer::start中调用 封装了一个listen fd相关…...

express session JWT JSON Web Token
了解 Session 认证的局限性 Session 认证机制需要配合 cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。 注意: 当前端…...

负载均衡策略 LVS
一、集群功能分类 1、LB (1) 概念: LB:负载均衡 (Load Balancing) 是一种分发网络流量的技术,LB 负载均衡的基本原理是将传入的网络流量分发到多个后端服务器,以确保这些服务器都承担相似的工作负载,从而避免某一台…...

驱动开发6 IO多路复用——epoll
核心操作:一棵树、一张表、三个接口 相关案例 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys…...
【python学习笔记——列表】
1、列表定义 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。 空列表 list[]非空列表 列表定义时例如list[‘csdn’, ‘is’ ,‘good’ ,2023],直接给列表内赋值 2、列表索引规则 列表名[start:stop:step],前闭后开,即取索引为start…...

TensorRT量化实战课YOLOv7量化:YOLOv7-PTQ量化(一)
目录 前言1. YOLOv7-PTQ量化流程2. 准备工作3. 插入QDQ节点3.1 自动插入QDQ节点3.2 手动插入QDQ节点 前言 手写 AI 推出的全新 TensorRT 模型量化实战课程,链接。记录下个人学习笔记,仅供自己参考。 该实战课程主要基于手写 AI 的 Latte 老师所出的 Tens…...

[微信小程序踩坑]微信小程序editor富文本组件渲染字符串时,内部图片超出大小导致无法正常渲染或回显(数据传输长度为 3458 KB,存在有性能问题!)
坑一:回显问题 富文本组件: <editor id"editor" name"{{name}}" style"font-size: 28rpx;color: #C9CDD4" read-only"{{true}}" placeholder"{{placeholder}}" bind:input"onChange11"…...
USACO12OPEN Balanced Cow Subsets G(meet in the middle)
洛谷P3067 [USACO12OPEN] Balanced Cow Subsets G 题目大意 我们定义一个奶牛集合 S S S是平衡的,当且仅当满足以下两个条件: S S S非空 S S S可以被划分为两个集合 A , B A,B A,B,满足 A A A里的奶牛产量之和等于 B B B里的牛奶产量之和 …...
GIT常用操作记录
1、后悔药:强制回退到某个具体历史提交记录,并强制推送到远程仓库 强制回退到某个具体历史提交记录,即要删除它之后的所有提交,可以用 git reset 命令。 首先找到目标提交记录的ID,可以在github远程仓库的历史提交记…...

【ETL工具】Datax-ETL-SqlServerToHDFS
🦄 个人主页——🎐个人主页 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 感谢点赞和关注 ,每天进步一点点!加油!&…...
Kubernetes (K8S)概述
1、K8S 是什么? K8S 的全称为 Kubernetes (K12345678S),PS:“嘛,写全称也太累了吧,不如整个缩写”。 1.1 作用 用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。 可以…...

11月14号|Move生态Meetup相约浪漫土耳其
Move是基于Rust编程语言,由Mysten Labs联合创始人兼CTO Sam Blackshear在Meta的Libra项目中开发而来,旨在为开发者提供比现有区块链语言更通用的开发语言。Sam的目标是创建Web3的JavaScript,即一种跨平台语言,使开发人员能够在多个…...
mac vim没有颜色 问题
vim ~/.vimrc syntax on set nu! set autoindent...

Servlet核心API
目录 HttpServlet init destory service 实例:处理get、post、put、delete请求 1.通过postman得到请求 2.通过ajax得到请求 HttpServletRequest 常见方法 前端给后端传参 1.GET,query string 2.POST,form 3.POST,json HttpSeverletRespons…...

crs 维护模式 exclusive mode
How To Validate ASM Instances And Diskgroups On A RAC Cluster (When CRS Does Not Start). (Doc ID 1609127.1)编辑To Bottom [rootrac1 ~]# ps -ef|grep grid root 2477 1 1 20:47 ? 00:00:51 /opt/oracle.ahf/jre/bin/java -server -Xms32m -Xmx64…...

【OpenCV实现平滑图像形态学变化】
文章目录 概要目标腐蚀膨胀开运算结构元素(内核)小结 概要 形态学变化是一组简单的图像操作,主要用于处理二值图像,即只包含黑和白两种颜色的图像。这些操作通常需要两个输入,原始图像和一个内核(kernel&a…...
Ubuntu服务器中java -jar 后台运行Spring Boot项目
问:我在我的服务器中java -jar 运行springboot项目,但是我操作不了命令了,必须要终止掉才能执行后面的操作,怎么样才能让他后台运行呢?比如我的jar包名是tools-boot-0.0.1-SNAPSHOT.jar 使用nohup命令: 在…...
微服务parent工程和子工程pom文件配置注意
parent工程 重要配置: <!-- 父工程 --><packaging>pom</packaging><!-- 聚合 --><modules><module>../base</module><module>../gateway</module><module>../user-service</module><mod…...

STM32G030F6P6点灯闪烁
前言 (1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动实习岗位,可C站直接私聊,或者邮件:zhangyixu02gmail.com,此消息至2025年1月1日前均有效 (2࿰…...
K8s开发人员也需要了解的相关知识
工作变动总结一下之前的笔记,整理一个速查的东西,方便之后查阅 K8s开发相关 1、k8s yml apiverison: Kubernetes (k8s) 的 API 版本表示资源定义在 API 服务器中的稳定性和支持程度。API 版本由一个字符串表示,如 v1 或 apps/v1,…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...