📄 warnetaddress.cpp
字号:
#include "StdAfx.h"#include "WarNetAddress.h" // class implementedusing namespace std;/////////////////////////////// PUBLIC /////////////////////////////////////////============================= LIFECYCLE ====================================WarNetAddress::WarNetAddress(){ Reset();}// WarNetAddressWarNetAddress::WarNetAddress(const std::string& from) throw(WarException){ Reset(); operator = (from);}WarNetAddress::WarNetAddress(const WarNetAddress& from){ operator = (from);}// WarNetAddressWarNetAddress::~WarNetAddress(){}// ~WarNetAddress//============================= OPERATORS ====================================WarNetAddress& WarNetAddress::operator = (const WarNetAddress& from) throw(WarException){ memcpy(&mAddr, &from.mAddr, sizeof(mAddr)); mDomainname = from.mDomainname; mIsResolved = from.mIsResolved; return *this;}// Resolv hostname | dotted_ip [: port | protocol_name]WarNetAddress& WarNetAddress::operator = (war_ccstr_t from) throw(WarException){ return operator = (string(from));}bool WarNetAddress::operator == (const WarNetAddress& from) const{ struct sockaddr_in *p1 = (sockaddr_in *)&mAddr; struct sockaddr_in *p2 = (sockaddr_in *)&from.mAddr; return ((p1->sin_family == p2->sin_family) && (p1->sin_port == p2->sin_port) && (p1->sin_addr.s_addr == p2->sin_addr.s_addr));}bool WarNetAddress::operator < (const WarNetAddress& from) const{ struct sockaddr_in *p1 = (sockaddr_in *)&mAddr; struct sockaddr_in *p2 = (sockaddr_in *)&from.mAddr; return !((p1->sin_family >= p2->sin_family) && (p1->sin_port >= p2->sin_port) && (p1->sin_addr.s_addr >= p2->sin_addr.s_addr));} WarNetAddress& WarNetAddress::operator = (const std::string& from) throw(WarException){ string from_name = from, port_name; war_port_t ipv4_port = 0; war_uint32_t ipv4_addr = INADDR_ANY; string::size_type delim = from.find(':'); if (delim != from.npos) { port_name = from.substr(delim +1); from_name.erase(delim); } if (!strcmp(from_name.c_str(), "*")) from_name = "0.0.0.0"; if (!port_name.empty()) { ipv4_port = atoi(port_name.c_str()); if (ipv4_port == 0) { struct protoent *pent = ::getprotobyname(port_name.c_str()); if (pent) ipv4_port = pent->p_proto; else { // We can handle some well known names if (!stricmp(port_name.c_str(), "ftp")) ipv4_port = 21; else if (!stricmp(port_name.c_str(), "ftp-data")) ipv4_port = 20; else if (!stricmp(port_name.c_str(), "www")) ipv4_port = 80; else if (!stricmp(port_name.c_str(), "nntp")) ipv4_port = 119; else if (!stricmp(port_name.c_str(), "smtp")) ipv4_port = 25; else if (!stricmp(port_name.c_str(), "pop3")) ipv4_port = 110; else WarThrow(WarError(WAR_NETERR_INVALID_PORT_OR_SERVICE), NULL); } } } if ((ipv4_addr = inet_addr(from_name.c_str())) == INADDR_NONE) { // Try a host-lookup. This may take some time... struct hostent *phost = ::gethostbyname(from_name.c_str()); if (phost) { if (phost->h_length != sizeof(ipv4_addr)) WarThrow(WarError(WAR_NETERR_UNSUPPORTED_FAMILY), NULL); ipv4_addr = *((war_uint32_t *)phost->h_addr); } else WarThrow(WarError(WAR_ERR_OBJECT_NOT_FOUND), NULL); } struct sockaddr_in *paddr = (sockaddr_in *)&mAddr; memset(&mAddr, 0, sizeof(mAddr)); // Initialize for ipv4 paddr->sin_family = AF_INET; paddr->sin_port = htons(ipv4_port); paddr->sin_addr.s_addr = ipv4_addr; UpdateDomainname(); return *this;}//============================= OPERATIONS ===================================void WarNetAddress::Reset(){ ::memset(&mAddr, 0, sizeof(mAddr)); mDomainname.empty(); mIsResolved = false;}void WarNetAddress::SetPort(war_port_t newPort){ ((struct sockaddr_in *)&mAddr)->sin_port = newPort;}void WarNetAddress::Resolv(bool doWaitForResult) throw(WarException){ if (mIsResolved) return; if (doWaitForResult) { struct hostent *phost = ::gethostbyaddr( (char *)(&GetSockAddr()), GetSockAddrLength(), GetFamily()); if (NULL == phost) WarThrow(WarException(WAR_ERR_DNS_LOOKUP_FAILED), NULL); mDomainname = phost->h_name; }}//============================= ACCESS ===================================/// Get the port-numberwar_port_t WarNetAddress::GetPort() const throw(WarException){ return ntohs(GetSockAddrIn().sin_port);}///const struct sockaddr& WarNetAddress::GetSockAddr() const throw(WarException){ return mAddr;}///const struct sockaddr_in& WarNetAddress::GetSockAddrIn() const throw(WarException){ return *(struct sockaddr_in *)&mAddr;}///const in_addr& WarNetAddress::GetInAddr() const throw(WarException){ return GetSockAddrIn().sin_addr;}// Get the family type (from struct sockaddr)int WarNetAddress::GetFamily() const throw(WarException){ if (IsEmpty()) WarThrow(WarError(WAR_ERR_INTERNAL_DATA_NOT_INITIALIZED), NULL); return mAddr.sa_family;}size_t WarNetAddress::GetSockAddrLength() const{ return sizeof(struct sockaddr);}std::string WarNetAddress::GetServiceName() const{ war_port_t port = GetPort(); string service_name; if (port) { struct servent *p = ::getservbyport(port, NULL); if (p) service_name = p->s_name; } return service_name;}void WarNetAddress::AssignSockaddr(const struct sockaddr *paddr, size_t length) throw(WarException){ if (length != sizeof(struct sockaddr)) WarThrow(WarError(WAR_NETERR_UNSUPPORTED_FAMILY), NULL); if (paddr) memcpy(&mAddr, paddr, length); else memset(&mAddr, 0, sizeof(mAddr)); UpdateDomainname();}//============================= INQUIRY ===================================std::string WarNetAddress::Explain() const{ const struct sockaddr_in& rin = GetSockAddrIn(); switch(rin.sin_family) { case AF_INET: { char buf[128]; sprintf(buf, "%d.%d.%d.%d:%d", WAR_IN_ADDR_B1(rin.sin_addr), WAR_IN_ADDR_B2(rin.sin_addr), WAR_IN_ADDR_B3(rin.sin_addr), WAR_IN_ADDR_B4(rin.sin_addr), GetPort()); string name = GetServiceName(); if (!name.empty()) { strcat(buf, "["); strcat(buf, name.c_str()); strcat(buf, "]"); } return buf; } default: return "***unknown network family***"; } return "*error*"; // Compiler food}bool WarNetAddress::IsEmpty() const{ const struct sockaddr_in& rin = GetSockAddrIn(); return (rin.sin_addr.s_addr == INADDR_ANY) && (rin.sin_port == 0);}const std::string WarNetAddress::GetDottedStr() const{ return ::inet_ntoa(GetInAddr());}/////////////////////////////// PROTECTED ///////////////////////////////////void WarNetAddress::UpdateDomainname(){ struct in_addr my_inaddr = GetInAddr(); switch(htonl(my_inaddr.s_addr)) { case INADDR_LOOPBACK: mDomainname = "localhost"; mIsResolved = true; break; case INADDR_ANY: mDomainname = "INADDR_ANY"; mIsResolved = true; break; case INADDR_NONE: mDomainname = "INADDR_NONE"; mIsResolved = true; break; default: mDomainname = GetDottedStr(); }}/////////////////////////////// PRIVATE ///////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -