目录
项目实战+新特性用法介绍
开源代码+博客解析+视频讲解
GitHub+CSDN+BiliBili同步更新,三个平台同名【岩禾溪】
GitHub代码链接:
项目讲解视频连接:
你的关注是我更新的最大动力
InetAddress.ixx
模块介绍
该模块名为 InetAddress
,用于处理网络地址的表示和操作。它依赖于 C++20 中的模块特性进行导出和导入相关头文件,并提供网络地址的基本功能。
类 InetAddress
:
-
构造函数:
explicit InetAddress(uint16_t port = 0, std::string_view ip = "127.0.0.1");
:这是一个构造函数,用于创建一个 InetAddress 类的实例。它接受一个端口号和一个 IP 地址字符串,默认情况下端口号为0,IP地址为 "127.0.0.1"。
-
成员函数:
std::string toIp() const;
:返回当前InetAddress
实例的 IP 地址字符串表示。std::string toIpPort() const;
:返回当前InetAddress
实例的 IP 地址和端口号的组合字符串表示。uint16_t toPort() const;
:返回当前InetAddress
实例的端口号。const sockaddr_in *getSockAddr() const;
:返回指向当前InetAddress
实例中 sockaddr_in 结构的指针。void setSockAddr(const sockaddr_in &addr);
:设置当前InetAddress
实例中的 sockaddr_in 结构。
C++20 新特性内容:
- Modules (模块):
export module InetAddress;
和export/import
关键字用于导出和导入模块,将InetAddress
类的定义和相关的头文件进行模块化管理。 - std::string_view:
std::string_view
是 C++17 引入的,但在 C++20 中得到了增强。它用于在不拷贝字符串的情况下表示和操作字符串。 - Uniform Initialization (统一初始化):在构造函数中,使用了统一初始化方式,允许在一个构造函数中同时提供多个默认参数值。
InetAddress.cpp
函数实现解释:
-
构造函数
InetAddress::InetAddress(uint16_t port, std::string_view ip)
:- 设置了
sockaddr_in
结构体的sin_family
成员为AF_INET
,表示使用 IPv4 地址族。 - 使用
htons()
函数将传入的port
(端口号)转换为网络字节序(Big-endian)。 - 使用
inet_pton()
函数将传入的ip
(IPv4 地址字符串)转换为网络字节序的二进制格式,存储到sockaddr_in
结构体的sin_addr
成员中。
- 设置了
-
成员函数
std::string InetAddress::toIp() const
:- 使用
inet_ntop()
函数将存储在sockaddr_in
结构体的sin_addr
中的网络字节序的 IPv4 地址转换为可读的点分十进制字符串格式,并返回该字符串。
- 使用
-
成员函数
std::string InetAddress::toIpPort() const
:- 调用
toIp()
函数获取点分十进制表示的 IP 地址字符串。 - 使用
ntohs()
函数将sockaddr_in
结构体中存储的网络字节序的端口号转换为主机字节序(Little-endian)的端口号。 - 使用
sprintf()
函数将 IP 地址字符串和端口号格式化为"ip:port"
的形式,并返回该字符串。
- 调用
Channel.ixx
模块介绍
该模块名为 Channel
,实现了一个用于管理文件描述符事件的类。它依赖于 EventLoop
类和其他一些头文件和类型,使用了 nocopyable
类作为基类。
类 Channel
:
-
构造函数:
Channel(EventLoop *loop, int fd);
:接受一个指向EventLoop
对象的指针和一个文件描述符作为参数,用于创建Channel
类的实例。
-
析构函数:
~Channel();
:析构函数用于释放资源,清理对象。
-
成员函数:
void handleEvent(Timestamp receiveTime);
:处理事件的方法,接收一个Timestamp
参数。- 四个
set
函数用于设置不同类型事件的回调函数。 tie(const std::shared_ptr<void> &);
:将Channel
与给定的shared_ptr
关联起来。- 多个操作函数用于控制事件的状态,如
enableReading()
、disableReading()
等。 remove()
:从EventLoop
中移除当前Channel
。
-
私有函数:
update()
:更新事件。handleEventWithGuard(Timestamp receiveTime);
:带有保护的事件处理函数。
Channel.cpp
模块导入和常量定义:
- 使用了
EventLoop
、sys/epoll.h
、Logger
和Channel
模块。 - 定义了三个常量
Channel::kNoneEvent
、Channel::kReadEvent
和Channel::kWriteEvent
,分别表示无事件、读事件和写事件,对应EPOLLIN
、EPOLLPRI
和EPOLLOUT
。
类 Channel
的函数实现:
-
构造函数
Channel::Channel(EventLoop *loop, int fd)
:- 接受一个指向
EventLoop
对象的指针和一个文件描述符作为参数。 - 初始化了
Channel
类的成员变量,如events_
、revents_
等。
- 接受一个指向
-
成员函数
void tie(const std::shared_ptr<void> &obj)
:- 将
Channel
与给定的shared_ptr
关联起来,标记为已关联状态。
- 将
-
成员函数
void update()
和void remove()
:- 这两个函数被注释掉了,通常用于在
EventLoop
中更新和移除当前的Channel
。
- 这两个函数被注释掉了,通常用于在
-
成员函数
void handleEvent(Timestamp receiveTime)
和void handleEventWithGuard(Timestamp receiveTime)
:handleEvent()
是对事件处理函数的调度器,检查是否与shared_ptr
相关联,并调用handleEventWithGuard()
。handleEventWithGuard()
是对具体事件的处理函数,根据触发的事件类型执行相应的回调函数,如读、写、错误或关闭。
关于注释部分:
- 代码中有一些注释掉的代码段,这里我还没调好,之后会更新,目前编译可以通过
- 这里包括了日志记录和
Logger
类的使用。这些部分将被用于调试或记录日志,在生产环境中会被用于追踪事件处理过程中的状态和信息。
更新Logger
删除了Logger.cpp,简化了Logger模块的内容,使用更加直观
Logger.ixx(更新)
总结
可以无所谓,不能无所获
——岩