⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketaddress.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
字号:
#ifdef POSIX#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#endif#include <cstring>#include <sstream>#include "byteorder.h"#include "common.h"#include "logging.h"#include "socketaddress.h"#ifdef WIN32#undef SetPortint inet_aton(const char * cp, struct in_addr * inp) {  inp->s_addr = inet_addr(cp);  return (inp->s_addr == INADDR_NONE) ? 0 : 1;}#endif // WIN32#ifdef _DEBUG#define DISABLE_DNS 0#else // !_DEBUG#define DISABLE_DNS 0#endif // !_DEBUGnamespace utils_base {SocketAddress::SocketAddress() {  Clear();}SocketAddress::SocketAddress(const std::string& hostname, int port, bool use_dns) {  SetIP(hostname, use_dns);  SetPort(port);}SocketAddress::SocketAddress(uint32 ip, int port) {  SetIP(ip);  SetPort(port);}SocketAddress::SocketAddress(const SocketAddress& addr) {  this->operator=(addr);}void SocketAddress::Clear() {  hostname_.clear();  ip_ = 0;  port_ = 0;}SocketAddress& SocketAddress::operator=(const SocketAddress& addr) {  hostname_ = addr.hostname_;  ip_ = addr.ip_;  port_ = addr.port_;  return *this;}void SocketAddress::SetIP(uint32 ip) {  hostname_.clear();  ip_ = ip;}bool SocketAddress::SetIP(const std::string& hostname, bool use_dns) {  hostname_ = hostname;  ip_ = 0;  return Resolve(true, use_dns);}void SocketAddress::SetResolvedIP(uint32 ip) {  ip_ = ip;}void SocketAddress::SetPort(int port) {  ASSERT((0 <= port) && (port < 65536));  port_ = port;}uint32 SocketAddress::ip() const {  return ip_;}uint16 SocketAddress::port() const {  return port_;}std::string SocketAddress::IPAsString() const {  if (!hostname_.empty())    return hostname_;  return IPToString(ip_);}std::string SocketAddress::PortAsString() const {  std::ostringstream ost;  ost << port_;  return ost.str();}std::string SocketAddress::ToString() const {  std::ostringstream ost;  ost << IPAsString();  ost << ":";  ost << port();  return ost.str();}bool SocketAddress::IsAny() const {  return (ip_ == 0);}bool SocketAddress::IsLocalIP() const {  return (ip_ >> 24) == 127;}bool SocketAddress::IsPrivateIP() const {  return ((ip_ >> 24) == 127) ||         ((ip_ >> 24) == 10) ||         ((ip_ >> 20) == ((172 << 4) | 1)) ||         ((ip_ >> 16) == ((192 << 8) | 168));}bool SocketAddress::IsUnresolved() const {  return IsAny() && !hostname_.empty();}bool SocketAddress::Resolve(bool force, bool use_dns) {  if (hostname_.empty()) {    // nothing to resolve  } else if (!force && !IsAny()) {    // already resolved  } else if (uint32 ip = StringToIP(hostname_, use_dns)) {    ip_ = ip;  } else {    return false;  }  return true;}bool SocketAddress::operator ==(const SocketAddress& addr) const {  return EqualIPs(addr) && EqualPorts(addr);}bool SocketAddress::operator <(const SocketAddress& addr) const {  if (ip_ < addr.ip_)    return true;  else if (addr.ip_ < ip_)    return false;  // We only check hostnames if both IPs are zero.  This matches EqualIPs()  if (addr.ip_ == 0) {    if (hostname_ < addr.hostname_)      return true;    else if (addr.hostname_ < hostname_)      return false;  }  return port_ < addr.port_;}bool SocketAddress::EqualIPs(const SocketAddress& addr) const {  return (ip_ == addr.ip_) && ((ip_ != 0) || (hostname_ == addr.hostname_));}bool SocketAddress::EqualPorts(const SocketAddress& addr) const {  return (port_ == addr.port_);}size_t SocketAddress::Hash() const {  size_t h = 0;  h ^= ip_;  h ^= port_ | (port_ << 16);  return h;}size_t SocketAddress::Size_() const {  return sizeof(ip_) + sizeof(port_);}void SocketAddress::Write_(char* buf, int len) const {  // TODO: Depending on how this is used, we may want/need to write hostname  ASSERT((size_t)len >= Size_());  reinterpret_cast<uint32*>(buf)[0] = ip_;  buf += sizeof(ip_);  reinterpret_cast<uint16*>(buf)[0] = port_;}void SocketAddress::Read_(const char* buf, int len) {  ASSERT((size_t)len >= Size_());  ip_ = reinterpret_cast<const uint32*>(buf)[0];  buf += sizeof(ip_);  port_ = reinterpret_cast<const uint16*>(buf)[0];}void SocketAddress::ToSockAddr(sockaddr_in* saddr) const {  memset(saddr, 0, sizeof(*saddr));  saddr->sin_family = AF_INET;  saddr->sin_port = HostToNetwork16(port_);  if (0 == ip_) {    saddr->sin_addr.s_addr = INADDR_ANY;  } else {    saddr->sin_addr.s_addr = HostToNetwork32(ip_);  }}void SocketAddress::FromSockAddr(const sockaddr_in& saddr) {  SetIP(NetworkToHost32(saddr.sin_addr.s_addr));  SetPort(NetworkToHost16(saddr.sin_port));}std::string SocketAddress::IPToString(uint32 ip) {  std::ostringstream ost;  ost << ((ip >> 24) & 0xff);  ost << '.';  ost << ((ip >> 16) & 0xff);  ost << '.';  ost << ((ip >> 8) & 0xff);  ost << '.';  ost << ((ip >> 0) & 0xff);  return ost.str();}uint32 SocketAddress::StringToIP(const std::string& hostname, bool use_dns) {  uint32 ip = 0;  in_addr addr;  if (inet_aton(hostname.c_str(), &addr) != 0) {    ip = NetworkToHost32(addr.s_addr);  } else if (use_dns) {    // Note: this is here so we can spot spurious DNS resolutions for a while    LOG(INFO) << "=== DNS RESOLUTION (" << hostname << ") ===";#if DISABLE_DNS    LOG(WARNING) << "*** DNS DISABLED ***";#if WIN32    WSASetLastError(WSAHOST_NOT_FOUND);#endif // WIN32#endif // DISABLE_DNS    if (hostent * pHost = gethostbyname(hostname.c_str())) {      ip = NetworkToHost32(*reinterpret_cast<uint32 *>(pHost->h_addr_list[0]));    } else {#if WIN32      LOG(LS_ERROR) << "gethostbyname error: " << WSAGetLastError();#else      LOG(LS_ERROR) << "gethostbyname error: " << strerror(h_errno);#endif    }    LOG(INFO) << hostname << " resolved to " << IPToString(ip);  }  return ip;}std::string SocketAddress::GetHostname() {  char hostname[256];  if (gethostname(hostname, ARRAY_SIZE(hostname)) == 0)    return hostname;  return "";}bool SocketAddress::GetLocalIPs(std::vector<uint32>& ips) {  ips.clear();  const std::string hostname = GetHostname();  if (hostname.empty())    return false;  if (hostent * pHost = gethostbyname(hostname.c_str())) {    for (size_t i=0; pHost->h_addr_list[i]; ++i) {      uint32 ip =        NetworkToHost32(*reinterpret_cast<uint32 *>(pHost->h_addr_list[i]));      ips.push_back(ip);    }    return !ips.empty();  }#if WIN32  LOG(LS_ERROR) << "gethostbyname error: " << WSAGetLastError();#else  LOG(LS_ERROR) << "gethostbyname error: " << strerror(h_errno);#endif  return false;}} // namespace utils_base

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -