网络地址和主机地址之间进行转换的类
#pragma once
#include "Common.hpp"
// 网络地址和主机地址之间进行转换的类class InetAddr
{
public:InetAddr(){}InetAddr(struct sockaddr_in &addr) : _addr(addr){// 网络转主机_port = ntohs(_addr.sin_port); // 从网络中拿到的!网络序列// _ip = inet_ntoa(_addr.sin_addr); // 4字节网络风格的IP -> 点分十进制的字符串风格的IPchar ipbuffer[64];inet_ntop(AF_INET, &_addr.sin_addr, ipbuffer, sizeof(_addr));_ip = ipbuffer;}InetAddr(const std::string &ip, uint16_t port) : _ip(ip), _port(port){// 主机转网络memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;inet_pton(AF_INET, _ip.c_str(), &_addr.sin_addr);_addr.sin_port = htons(_port);// local.sin_addr.s_addr = inet_addr(_ip.c_str()); // TODO}InetAddr(uint16_t port) :_port(port),_ip(){// 主机转网络memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;_addr.sin_addr.s_addr = INADDR_ANY;_addr.sin_port = htons(_port);}uint16_t Port() { return _port; }std::string Ip() { return _ip; }const struct sockaddr_in &NetAddr() { return _addr; }const struct sockaddr *NetAddrPtr(){return CONV(_addr);}socklen_t NetAddrLen(){return sizeof(_addr);}bool operator==(const InetAddr &addr){return addr._ip == _ip && addr._port == _port;}std::string StringAddr(){return _ip + ":" + std::to_string(_port);}~InetAddr(){}private:struct sockaddr_in _addr;std::string _ip;uint16_t _port;
};
轻量级的网络地址封装类 InetAddr
,它封装了 sockaddr_in
,提供了更友好的 C++ 接口,方便在主机格式(ip:port
字符串)和网络格式(sockaddr_in
)之间转换。
✅ 核心功能总结
功能 | 说明 |
---|---|
构造器 | 支持从 sockaddr_in 、ip+port 、仅port 三种方式构造 |
地址转换 | 自动完成 主机字节序 ↔ 网络字节序 ,字符串IP ↔ 二进制IP |
接口封装 | 提供 Ip() 、Port() 、NetAddr() 等易用接口 |
比较与打印 | 支持 == 比较、StringAddr() 打印 |
✅ 逐段讲解
1. 默认构造器
InetAddr() {}
空构造器,用于后续手动设置地址。
2. 从 sockaddr_in
构造
InetAddr(struct sockaddr_in &addr) : _addr(addr)
{_port = ntohs(_addr.sin_port);char ipbuffer[64];inet_ntop(AF_INET, &_addr.sin_addr, ipbuffer, sizeof(ipbuffer));_ip = ipbuffer;
}
作用:从网络地址结构体中提取
ip
和port
(主机字节序)。注意:
inet_ntop
比inet_ntoa
更现代、线程安全。
3. 从 ip + port
构造
InetAddr(const std::string &ip, uint16_t port) : _ip(ip), _port(port)
{memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;inet_pton(AF_INET, _ip.c_str(), &_addr.sin_addr);_addr.sin_port = htons(_port);
}
作用:把用户给的
ip:port
转成网络格式sockaddr_in
。
4. 仅指定端口(监听用)
InetAddr(uint16_t port) : _port(port), _ip()
{memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;_addr.sin_addr.s_addr = INADDR_ANY;_addr.sin_port = htons(_port);
}
作用:用于服务器监听,绑定任意 IP(
0.0.0.0
)。
5. 常用接口
uint16_t Port() { return _port; }
std::string Ip() { return _ip; }
const struct sockaddr_in &NetAddr() { return _addr; }
const struct sockaddr *NetAddrPtr() { return CONV(_addr); }
socklen_t NetAddrLen() { return sizeof(_addr); }
提供访问内部字段的快捷方式。
6. 比较与打印
bool operator==(const InetAddr &addr)
{return addr._ip == _ip && addr._port == _port;
}
std::string StringAddr()
{return _ip + ":" + std::to_string(_port);
}
方便调试或日志输出,如
InetAddr addr("127.0.0.1", 8080); std::cout << addr.StringAddr(); // 输出:127.0.0.1:8080
✅ 一句话总结
InetAddr
是对传统sockaddr_in
的 C++ 封装,屏蔽了底层字节序和字符串转换细节,极大简化了网络地址的构造、访问与打印。