#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++ 封裝,屏蔽了底層字節序和字符串轉換細節,極大簡化了網絡地址的構造、訪問與打印。