当前位置: 首页 > news >正文

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类用于创建套接字&#xff0c;设置套接字选项&#xff0c;调用socket()->bind()->listen()->accept()函数&#xff0c;接受连接&#xff0c;然后调用TcpServer设置的connect事件的回调。 listen()//在TcpServer::start中调用 封装了一个listen fd相关…...

express session JWT JSON Web Token

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

负载均衡策略 LVS

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

驱动开发6 IO多路复用——epoll

核心操作&#xff1a;一棵树、一张表、三个接口 相关案例 #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]&#xff0c;直接给列表内赋值 2、列表索引规则 列表名[start:stop:step]&#xff0c;前闭后开&#xff0c;即取索引为start…...

TensorRT量化实战课YOLOv7量化:YOLOv7-PTQ量化(一)

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

[微信小程序踩坑]微信小程序editor富文本组件渲染字符串时,内部图片超出大小导致无法正常渲染或回显(数据传输长度为 3458 KB,存在有性能问题!)

坑一&#xff1a;回显问题 富文本组件&#xff1a; <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是平衡的&#xff0c;当且仅当满足以下两个条件&#xff1a; S S S非空 S S S可以被划分为两个集合 A , B A,B A,B&#xff0c;满足 A A A里的奶牛产量之和等于 B B B里的牛奶产量之和 …...

GIT常用操作记录

1、后悔药&#xff1a;强制回退到某个具体历史提交记录&#xff0c;并强制推送到远程仓库 强制回退到某个具体历史提交记录&#xff0c;即要删除它之后的所有提交&#xff0c;可以用 git reset 命令。 首先找到目标提交记录的ID&#xff0c;可以在github远程仓库的历史提交记…...

【ETL工具】Datax-ETL-SqlServerToHDFS

&#x1f984; 个人主页——&#x1f390;个人主页 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; 感谢点赞和关注 &#xff0c;每天进步一点点&#xff01;加油&#xff01;&…...

Kubernetes (K8S)概述

1、K8S 是什么&#xff1f; K8S 的全称为 Kubernetes (K12345678S)&#xff0c;PS&#xff1a;“嘛&#xff0c;写全称也太累了吧&#xff0c;不如整个缩写”。 1.1 作用 用于自动部署、扩展和管理“容器化&#xff08;containerized&#xff09;应用程序”的开源系统。 可以…...

11月14号|Move生态Meetup相约浪漫土耳其

Move是基于Rust编程语言&#xff0c;由Mysten Labs联合创始人兼CTO Sam Blackshear在Meta的Libra项目中开发而来&#xff0c;旨在为开发者提供比现有区块链语言更通用的开发语言。Sam的目标是创建Web3的JavaScript&#xff0c;即一种跨平台语言&#xff0c;使开发人员能够在多个…...

mac vim没有颜色 问题

vim ~/.vimrc syntax on set nu! set autoindent...

Servlet核心API

目录 HttpServlet init destory service 实例&#xff1a;处理get、post、put、delete请求 1.通过postman得到请求 2.通过ajax得到请求 HttpServletRequest 常见方法 前端给后端传参 1.GET,query string 2.POST,form 3.POST&#xff0c;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实现平滑图像形态学变化】

文章目录 概要目标腐蚀膨胀开运算结构元素&#xff08;内核&#xff09;小结 概要 形态学变化是一组简单的图像操作&#xff0c;主要用于处理二值图像&#xff0c;即只包含黑和白两种颜色的图像。这些操作通常需要两个输入&#xff0c;原始图像和一个内核&#xff08;kernel&a…...

Ubuntu服务器中java -jar 后台运行Spring Boot项目

问&#xff1a;我在我的服务器中java -jar 运行springboot项目&#xff0c;但是我操作不了命令了&#xff0c;必须要终止掉才能执行后面的操作&#xff0c;怎么样才能让他后台运行呢&#xff1f;比如我的jar包名是tools-boot-0.0.1-SNAPSHOT.jar 使用nohup命令&#xff1a; 在…...

微服务parent工程和子工程pom文件配置注意

parent工程 重要配置&#xff1a; <!-- 父工程 --><packaging>pom</packaging><!-- 聚合 --><modules><module>../base</module><module>../gateway</module><module>../user-service</module><mod…...

STM32G030F6P6点灯闪烁

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff08;2&#xff0…...

K8s开发人员也需要了解的相关知识

工作变动总结一下之前的笔记&#xff0c;整理一个速查的东西&#xff0c;方便之后查阅 K8s开发相关 1、k8s yml apiverison: Kubernetes (k8s) 的 API 版本表示资源定义在 API 服务器中的稳定性和支持程度。API 版本由一个字符串表示&#xff0c;如 v1 或 apps/v1&#xff0c…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...

SpringCloud优势

目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...