[岩禾溪] C++20项目 muduo网络库 项目实战 (2)InetAddress & Channel
目录
项目实战+新特性用法介绍
开源代码+博客解析+视频讲解
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(更新)
总结
可以无所谓,不能无所获
——岩

浙公网安备 33010602011771号