muduo网络库核心代码阅读(Timestamp,InetAddress)(2)
TimeStamp
TiemStamp类是muduo中的时间戳类,用于获取当前时间的格式化字符串。
成员变量
int64_t microSecondsSinceEpoch_;
TimeStamp类只有一个成员变量microSecondsSinceEpoch_,它保存了从1970年1月1日00:00:00 UTC到当前时间的微秒数。由于只有一个int64_t类型的成员变量,他的值传递非常高效。而且该类本身无法修改(没有提供修改成员变量的接口),并只能通过值传递(继承了copyable)。
核心方法
now
now()是TimeStamp类的静态方法,用于获取当前时间的TimeStamp对象。
// TimeStamp.h
static Timestamp now();
// TimeStamp.cc
Timestamp Timestamp::now()
{
/*timeval结构体定义:
struct timeval
{
long tv_sec; //秒数
long tv_usec; //微妙数
};
*/
struct timeval tv;
gettimeofday(&tv, NULL); //获取当前时间(从1970年1月1日00:00:00 UTC到当前时间的微秒数)
int64_t seconds = tv.tv_sec;
return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec); //获取总微妙数
}
toString
toString()是TimeStamp类的成员方法,用于获取当前时间的格式化字符串,形式为seconds.microseconds。
string Timestamp::toString() const
{
char buf[32] = {0};
int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond; //获取秒数
int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond; //获取微妙数
snprintf(buf, sizeof(buf), "%" PRId64 ".%06" PRId64 "", seconds, microseconds); //拼接,PRId64是用于格式化 int64_t 类型整数的宏
return buf;
}
toFormattedString
toFormattedString()是TimeStamp类的成员方法,用于获取当前时间的格式化字符串,形式为Ymd H:M:S seconds.microseconds。
string Timestamp::toFormattedString(bool showMicroseconds) const
{
char buf[64] = {0};
time_t seconds = static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
struct tm tm_time;
gmtime_r(&seconds, &tm_time);
if (showMicroseconds) //判断是否显示微秒(默认显示)
{
int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d",
tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
microseconds);
}
else
{
snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d",
tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
}
return buf;
}
实例
#include <muduo/base/Timestamp.h>
#include <iostream>
int main(){
std::cout << muduo::Timestamp::now().toString() << std::endl;
std::cout << muduo::Timestamp::now().toFormattedString() << std::endl;
return 0;
}
$ g++ test.cpp -o test -lmuduo_base
$ ./test
输出:
1737375966.121036
20250120 12:26:06.121244
InetAddress
InetAddress类是muduo中的网络地址类,用于表示IP地址和端口号。
类设计
InetAddress本身不是pod类型(plain old data),但他旨在设计为一个类似pod的接口类。
/// This is an POD interface class.
class InetAddress : public muduo::copyable
{
//...
};
成员变量
成员变量为一个联合体,支持IPV4地址和IPV6地址,大小为IPV6地址大小。
union
{
struct sockaddr_in addr_;
struct sockaddr_in6 addr6_;
};
构造函数
/// Constructs an endpoint with given port number.
/// Mostly used in TcpServer listening.
explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false);
/// Constructs an endpoint with given ip and port.
/// @c ip should be "1.2.3.4"
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
/// InetAddress只有一个包含sockaddr_in和sockaddr_in6的联合体,所以通过以下两种构造函数,可以很方便的实现地址的转换
/// Constructs an endpoint with given struct @c sockaddr_in
/// Mostly used when accepting new connections
explicit InetAddress(const struct sockaddr_in& addr)
: addr_(addr)
{ }
explicit InetAddress(const struct sockaddr_in6& addr)
: addr6_(addr)
{ }
//实现
InetAddress::InetAddress(uint16_t portArg, bool loopbackOnly, bool ipv6)
{
static_assert(offsetof(InetAddress, addr6_) == 0, "addr6_ offset 0");
static_assert(offsetof(InetAddress, addr_) == 0, "addr_ offset 0");
if (ipv6)
{
memZero(&addr6_, sizeof addr6_); //清空addr6_
addr6_.sin6_family = AF_INET6;
in6_addr ip = loopbackOnly ? in6addr_loopback : in6addr_any;
addr6_.sin6_addr = ip;
addr6_.sin6_port = sockets::hostToNetwork16(portArg); //转换端口号为网络字节序
}
else
{
memZero(&addr_, sizeof addr_);
addr_.sin_family = AF_INET;
in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny;
addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip); //转换IP地址为网络字节序
addr_.sin_port = sockets::hostToNetwork16(portArg); //转换端口号为网络字节序
}
}
核心方法
InetAddress提供了一系列接口来获取地址和端口号。sockets命名空间中定义了一系列关于socket的操作函数,方便操作。
sa_family_t family() const { return addr_.sin_family; }
string toIp() const;
string toIpPort() const;
uint16_t port() const;
//实现
string InetAddress::toIpPort() const
{
char buf[64] = "";
sockets::toIpPort(buf, sizeof buf, getSockAddr());
return buf;
}
string InetAddress::toIp() const
{
char buf[64] = "";
sockets::toIp(buf, sizeof buf, getSockAddr());
return buf;
}
uint16_t InetAddress::port() const
{
return sockets::networkToHost16(portNetEndian());
}
分类:
C/C++
, C/C++ / muduo网络库阅读
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现