ipaddress.cpp.svn-base
来自「很好用的网络封装库,不熟悉网络编程的人也可以使用。使用风格良好的标准c++编写。」· SVN-BASE 代码 · 共 802 行 · 第 1/2 页
SVN-BASE
802 行
//
// IPAddress.cpp
//
// $Id: //poco/1.3/Net/src/IPAddress.cpp#6 $
//
// Library: Net
// Package: NetCore
// Module: IPAddress
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "Poco/Net/IPAddress.h"
#include "Poco/Net/NetException.h"
#include "Poco/RefCountedObject.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Types.h"
#include <algorithm>
#include <cstring>
using Poco::RefCountedObject;
using Poco::NumberFormatter;
using Poco::UInt8;
using Poco::UInt16;
using Poco::UInt32;
namespace Poco {
namespace Net {
//
// IPAddressImpl
//
class IPAddressImpl: public RefCountedObject
{
public:
virtual std::string toString() const = 0;
virtual poco_socklen_t length() const = 0;
virtual const void* addr() const = 0;
virtual IPAddress::Family family() const = 0;
virtual int af() const = 0;
virtual bool isWildcard() const = 0;
virtual bool isBroadcast() const = 0;
virtual bool isLoopback() const = 0;
virtual bool isMulticast() const = 0;
virtual bool isLinkLocal() const = 0;
virtual bool isSiteLocal() const = 0;
virtual bool isIPv4Mapped() const = 0;
virtual bool isIPv4Compatible() const = 0;
virtual bool isWellKnownMC() const = 0;
virtual bool isNodeLocalMC() const = 0;
virtual bool isLinkLocalMC() const = 0;
virtual bool isSiteLocalMC() const = 0;
virtual bool isOrgLocalMC() const = 0;
virtual bool isGlobalMC() const = 0;
virtual void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet) = 0;
virtual IPAddressImpl* clone() const = 0;
protected:
IPAddressImpl()
{
}
virtual ~IPAddressImpl()
{
}
private:
IPAddressImpl(const IPAddressImpl&);
IPAddressImpl& operator = (const IPAddressImpl&);
};
class IPv4AddressImpl: public IPAddressImpl
{
public:
IPv4AddressImpl()
{
std::memset(&_addr, 0, sizeof(_addr));
}
IPv4AddressImpl(const void* addr)
{
std::memcpy(&_addr, addr, sizeof(_addr));
}
std::string toString() const
{
const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);
std::string result;
result.reserve(16);
result.append(NumberFormatter::format(bytes[0]));
result.append(".");
result.append(NumberFormatter::format(bytes[1]));
result.append(".");
result.append(NumberFormatter::format(bytes[2]));
result.append(".");
result.append(NumberFormatter::format(bytes[3]));
return result;
}
poco_socklen_t length() const
{
return sizeof(_addr);
}
const void* addr() const
{
return &_addr;
}
IPAddress::Family family() const
{
return IPAddress::IPv4;
}
int af() const
{
return AF_INET;
}
bool isWildcard() const
{
return _addr.s_addr == INADDR_ANY;
}
bool isBroadcast() const
{
return _addr.s_addr == INADDR_NONE;
}
bool isLoopback() const
{
return ntohl(_addr.s_addr) == 0x7F000001; // 127.0.0.1
}
bool isMulticast() const
{
return (ntohl(_addr.s_addr) & 0xF0000000) == 0xE0000000; // 224.0.0.0/24 to 239.0.0.0/24
}
bool isLinkLocal() const
{
return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xA9FE0000; // 169.254.0.0/16
}
bool isSiteLocal() const
{
UInt32 addr = ntohl(_addr.s_addr);
return (addr & 0xFF000000) == 0x0A000000 || // 10.0.0.0/24
(addr & 0xFFFF0000) == 0xC0A80000 || // 192.68.0.0/16
addr >= 0xAC100000 && addr <= 0xAC1FFFFF; // 172.16.0.0 to 172.31.255.255
}
bool isIPv4Compatible() const
{
return true;
}
bool isIPv4Mapped() const
{
return true;
}
bool isWellKnownMC() const
{
return (ntohl(_addr.s_addr) & 0xFFFFFF00) == 0xE0000000; // 224.0.0.0/8
}
bool isNodeLocalMC() const
{
return false;
}
bool isLinkLocalMC() const
{
return (ntohl(_addr.s_addr) & 0xFF000000) == 0xE0000000; // 244.0.0.0/24
}
bool isSiteLocalMC() const
{
return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFFF0000; // 239.255.0.0/16
}
bool isOrgLocalMC() const
{
return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFC00000; // 239.192.0.0/16
}
bool isGlobalMC() const
{
UInt32 addr = ntohl(_addr.s_addr);
return addr >= 0xE0000100 && addr <= 0xEE000000; // 224.0.1.0 to 238.255.255.255
}
static IPv4AddressImpl* parse(const std::string& addr)
{
if (addr.empty()) return 0;
#if defined(_WIN32)
struct in_addr ia;
ia.s_addr = inet_addr(addr.c_str());
if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
return 0;
else
return new IPv4AddressImpl(&ia);
#else
#if __GNUC__ < 3
struct in_addr ia;
ia.s_addr = inet_addr(addr.c_str());
if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
return 0;
else
return new IPv4AddressImpl(&ia);
#else
struct in_addr ia;
if (inet_aton(addr.c_str(), &ia))
return new IPv4AddressImpl(&ia);
else
return 0;
#endif
#endif
}
void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet)
{
poco_assert (pMask->af() == AF_INET && pSet->af() == AF_INET);
_addr.s_addr &= static_cast<const IPv4AddressImpl*>(pMask)->_addr.s_addr;
_addr.s_addr |= static_cast<const IPv4AddressImpl*>(pSet)->_addr.s_addr & ~static_cast<const IPv4AddressImpl*>(pMask)->_addr.s_addr;
}
IPAddressImpl* clone() const
{
return new IPv4AddressImpl(&_addr);
}
private:
struct in_addr _addr;
};
#if defined(POCO_HAVE_IPv6)
class IPv6AddressImpl: public IPAddressImpl
{
public:
IPv6AddressImpl()
{
std::memset(&_addr, 0, sizeof(_addr));
}
IPv6AddressImpl(const void* addr)
{
std::memcpy(&_addr, addr, sizeof(_addr));
}
std::string toString() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
if (isIPv4Compatible() || isIPv4Mapped())
{
std::string result;
result.reserve(24);
if (words[5] == 0)
result.append("::");
else
result.append("::FFFF:");
const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);
result.append(NumberFormatter::format(bytes[12]));
result.append(".");
result.append(NumberFormatter::format(bytes[13]));
result.append(".");
result.append(NumberFormatter::format(bytes[14]));
result.append(".");
result.append(NumberFormatter::format(bytes[15]));
return result;
}
else
{
std::string result;
result.reserve(46);
bool zeroSequence = false;
int i = 0;
while (i < 8)
{
if (!zeroSequence && words[i] == 0)
{
int zi = i;
while (zi < 8 && words[zi] == 0) ++zi;
if (zi > i + 1)
{
i = zi;
result.append(":");
zeroSequence = true;
}
}
if (i > 0) result.append(":");
if (i < 8) result.append(NumberFormatter::formatHex(ntohs(words[i++])));
}
return result;
}
}
poco_socklen_t length() const
{
return sizeof(_addr);
}
const void* addr() const
{
return &_addr;
}
IPAddress::Family family() const
{
return IPAddress::IPv6;
}
int af() const
{
return AF_INET6;
}
bool isWildcard() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 0;
}
bool isBroadcast() const
{
return false;
}
bool isLoopback() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 1;
}
bool isMulticast() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (words[0] & 0xFFE0) == 0xFF00;
}
bool isLinkLocal() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (words[0] & 0xFFE0) == 0xFE80;
}
bool isSiteLocal() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (words[0] & 0xFFE0) == 0xFEC0;
}
bool isIPv4Compatible() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0;
}
bool isIPv4Mapped() const
{
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0xFFFF;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?