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

📄 sockets.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 5 页
字号:
      //sin6_scope_id, should be taken into account for link local addresses
      return;
#endif
    case AF_INET: 
      if (ai_addrlen < (int)sizeof(sockaddr_in))
        break;

      version = 4;
      v.four = ((struct sockaddr_in  *)ai_addr)->sin_addr;
      return;
  }
  version = 0;
}

#endif


#ifdef __NUCLEUS_NET__
PIPSocket::Address::Address(const struct id_struct & addr)
{
  operator=(addr);
}


PIPSocket::Address & PIPSocket::Address::operator=(const struct id_struct & addr)
{
  s_addr = (((unsigned long)addr.is_ip_addrs[0])<<24) +
           (((unsigned long)addr.is_ip_addrs[1])<<16) +
           (((unsigned long)addr.is_ip_addrs[2])<<8) +
           (((unsigned long)addr.is_ip_addrs[3]));
  return *this;
}
#endif
 

PIPSocket::Address & PIPSocket::Address::operator=(const in_addr & addr)
{
  version = 4;
  v.four = addr;
  return *this;
}

#if P_HAS_IPV6
PIPSocket::Address & PIPSocket::Address::operator=(const in6_addr & addr)
{
  version = 6;
  v.six = addr;
  return *this;
}
#endif


PObject::Comparison PIPSocket::Address::Compare(const PObject & obj) const
{
  const PIPSocket::Address & other = (const PIPSocket::Address &)obj;

  if (version < other.version)
    return LessThan;
  if (version > other.version)
    return GreaterThan;

#if P_HAS_IPV6
  if (version == 6) {
    int result = memcmp(&v.six, &other.v.six, sizeof(v.six));
    if (result < 0)
      return LessThan;
    if (result > 0)
      return GreaterThan;
    return EqualTo;
  }
#endif

  if ((DWORD)*this < other)
    return LessThan;
  if ((DWORD)*this > other)
    return GreaterThan;
  return EqualTo;
}

#if P_HAS_IPV6
bool PIPSocket::Address::operator*=(const PIPSocket::Address & addr) const
{
  if (version == addr.version)
    return operator==(addr);

  if (this->GetVersion() == 6 && this->IsV4Mapped()) 
    return PIPSocket::Address((*this)[12], (*this)[13], (*this)[14], (*this)[15]) == addr;
  else if (addr.GetVersion() == 6 && addr.IsV4Mapped()) 
    return *this == PIPSocket::Address(addr[12], addr[13], addr[14], addr[15]);
  return PFalse;
}

bool PIPSocket::Address::operator==(in6_addr & addr) const
{
  PIPSocket::Address a(addr);
  return Compare(a) == EqualTo;
}
#endif


bool PIPSocket::Address::operator==(in_addr & addr) const
{
  PIPSocket::Address a(addr);
  return Compare(a) == EqualTo;
}


bool PIPSocket::Address::operator==(DWORD dw) const
{
  if (dw != 0)
    return (DWORD)*this == dw;

  return !IsValid();
}


PIPSocket::Address & PIPSocket::Address::operator=(const PString & dotNotation)
{
  version = 0;
  memset(&v, 0, sizeof(v));

#if P_HAS_IPV6

  struct addrinfo *res = NULL;
  struct addrinfo hints = { AI_NUMERICHOST, PF_UNSPEC }; // Could be IPv4: x.x.x.x or IPv6: x:x:x:x::x

  if (getaddrinfo((const char *)dotNotation, NULL , &hints, &res) == 0) {
    if (res->ai_family == PF_INET6) {
      // IPv6 addr
      version = 6;
      struct sockaddr_in6 * addr_in6 = (struct sockaddr_in6 *)res->ai_addr;
      v.six = addr_in6->sin6_addr;
    } else {
      // IPv4 addr
      version = 4;
      struct sockaddr_in * addr_in = (struct sockaddr_in *)res->ai_addr;
      v.four = addr_in->sin_addr;
    }
    freeaddrinfo(res);
  }

#else //P_HAS_IPV6

  DWORD iaddr;
  if (dotNotation.FindSpan("0123456789.") == P_MAX_INDEX &&
                    (iaddr = ::inet_addr((const char *)dotNotation)) != (DWORD)INADDR_NONE) {
    version = 4;
    v.four.s_addr = iaddr;
  }

#endif

  else {
    PINDEX percent = dotNotation.Find('%');
    if (percent != P_MAX_INDEX) {
      PString iface = dotNotation.Mid(percent+1);
      if (!iface.IsEmpty()) {
        PIPSocket::InterfaceTable interfaceTable;
        if (PIPSocket::GetInterfaceTable(interfaceTable)) {
          for (PINDEX i = 0; i < interfaceTable.GetSize(); i++) {
            if (interfaceTable[i].GetName().NumCompare(iface) == EqualTo) {
              *this = interfaceTable[i].GetAddress();
              break;
            }
          }
        }
      }
    }
  }

  return *this;
}


PString PIPSocket::Address::AsString() const
{
#if defined(P_VXWORKS)
  char ipStorage[INET_ADDR_LEN];
  inet_ntoa_b(v.four, ipStorage);
  return ipStorage;    
#else
# if defined(P_HAS_IPV6)
  if (version == 6) {
    PString str;
    Psockaddr sa(*this, 0);
    PAssertOS(getnameinfo(sa, sa.GetSize(), str.GetPointer(1024), 1024, NULL, 0, NI_NUMERICHOST) == 0);
    PINDEX percent = str.Find('%'); // used for scoped address e.g. fe80::1%ne0, (ne0=network interface 0)
    if (percent != P_MAX_INDEX)
      str[percent] = '\0';
    str.MakeMinimumSize();
    return str;
  }
#endif // P_HAS_IPV6
# if defined(P_HAS_INET_NTOP)
  PString str;
  if (inet_ntop(AF_INET, (const void *)&v.four, str.GetPointer(INET_ADDRSTRLEN), INET_ADDRSTRLEN) == NULL)
    return PString::Empty();
  str.MakeMinimumSize();
  return str;
# else
  static PCriticalSection x;
  PWaitAndSignal m(x);
  return inet_ntoa(v.four);
#endif // P_HAS_INET_NTOP
#endif // P_VXWORKS
}


PBoolean PIPSocket::Address::FromString(const PString & dotNotation)
{
  (*this) = dotNotation;
  return IsValid();

}


PIPSocket::Address::operator PString() const
{
  return AsString();
}


PIPSocket::Address::operator in_addr() const
{
  if (version != 4)
    return inaddr_empty;

  return v.four;
}


#if P_HAS_IPV6
PIPSocket::Address::operator in6_addr() const
{
  if (version != 6)
    return any6.v.six;

  return v.six;
}
#endif


BYTE PIPSocket::Address::operator[](PINDEX idx) const
{
  PASSERTINDEX(idx);
#if P_HAS_IPV6
  if (version == 6) {
    PAssert(idx <= 15, PInvalidParameter);
    return v.six.s6_addr[idx];
  }
#endif

  PAssert(idx <= 3, PInvalidParameter);
  return ((BYTE *)&v.four)[idx];
}


ostream & operator<<(ostream & s, const PIPSocket::Address & a)
{
  return s << a.AsString();
}

istream & operator>>(istream & s, PIPSocket::Address & a)
{
/// Not IPv6 ready !!!!!!!!!!!!!
  char dot1, dot2, dot3;
  unsigned b1, b2, b3, b4;
  s >> b1;
  if (!s.fail()) {
    if (s.peek() != '.')
      a = htonl(b1);
    else {
      s >> dot1 >> b2 >> dot2 >> b3 >> dot3 >> b4;
      if (!s.fail() && dot1 == '.' && dot2 == '.' && dot3 == '.')
        a = PIPSocket::Address((BYTE)b1, (BYTE)b2, (BYTE)b3, (BYTE)b4);
    }
  }
  return s;
}


PINDEX PIPSocket::Address::GetSize() const
{
  switch (version) {
#if P_HAS_IPV6
    case 6 :
      return 16;
#endif

    case 4 :
      return 4;
  }

  return 0;
}


PBoolean PIPSocket::Address::IsValid() const
{
  switch (version) {
#if P_HAS_IPV6
    case 6 :
      return memcmp(&v.six, &any6.v.six, sizeof(v.six)) != 0;
#endif

    case 4 :
      return (DWORD)*this != INADDR_ANY;
  }
  return PFalse;
}


PBoolean PIPSocket::Address::IsLoopback() const
{
#if P_HAS_IPV6
  if (version == 6)
    return IN6_IS_ADDR_LOOPBACK(&v.six);
#endif
  return *this == loopback4;
}


PBoolean PIPSocket::Address::IsBroadcast() const
{
#if P_HAS_IPV6
  if (version == 6) // In IPv6, no broadcast exist. Only multicast
    return PFalse;
#endif

  return *this == broadcast4;
}

PBoolean PIPSocket::Address::IsRFC1918() const 
{ 
#if P_HAS_IPV6
  if (version == 6) {
    if (IN6_IS_ADDR_LINKLOCAL(&v.six) || IN6_IS_ADDR_SITELOCAL(&v.six))
      return PTrue;
    if (IsV4Mapped())
      return PIPSocket::Address((*this)[12], (*this)[13], (*this)[14], (*this)[15]).IsRFC1918();
  }
#endif
  return (Byte1() == 10)
          ||
          (
            (Byte1() == 172)
            &&
            (Byte2() >= 16) && (Byte2() <= 31)
          )
          ||
          (
            (Byte1() == 192) 
            &&
            (Byte2() == 168)
          );
}

PIPSocket::InterfaceEntry::InterfaceEntry()
  : ipAddr(GetDefaultIpAny())
  , netMask(GetDefaultIpAny())
{
}

PIPSocket::InterfaceEntry::InterfaceEntry(const PString & _name,
                                          const Address & _addr,
                                          const Address & _mask,
                                          const PString & _macAddr
#if P_HAS_IPV6
                                         ,const PString & _ip6Addr
#endif
                                         )
  : name(_name.Trim()),
    ipAddr(_addr),
    netMask(_mask),
    macAddr(_macAddr)
#if P_HAS_IPV6
    , ip6Addr(_ip6Addr)
#endif
{
}


void PIPSocket::InterfaceEntry::PrintOn(ostream & strm) const
{
  strm << ipAddr;
#if P_HAS_IPV6
  if (!ip6Addr)
    strm << " [" << ip6Addr << ']';
#endif
  if (!macAddr)
    strm << " <" << macAddr << '>';
  if (!name)
    strm << " (" << name << ')';
}


#ifdef __NUCLEUS_NET__
PBoolean PIPSocket::GetInterfaceTable(InterfaceTable & table)
{
    InterfaceEntry *IE;
    list<IPInterface>::iterator i;
    for(i=Route4Configuration->Getm_IPInterfaceList().begin();
            i!=Route4Configuration->Getm_IPInterfaceList().end();
            i++)
    {
        char ma[6];
        for(int j=0; j<6; j++) ma[j]=(*i).Getm_macaddr(j);
        IE = new InterfaceEntry((*i).Getm_name().c_str(), (*i).Getm_ipaddr(), ma );
        if(!IE) return false;
        table.Append(IE);
    }
    return true;
}
#endif

PBoolean PIPSocket::GetNetworkInterface(PIPSocket::Address & addr)
{
  PIPSocket::InterfaceTable interfaceTable;
  if (PIPSocket::GetInterfaceTable(interfaceTable)) {
    PINDEX i;
    for (i = 0; i < interfaceTable.GetSize(); ++i) {
      PIPSocket::Address localAddr = interfaceTable[i].GetAddress();
      if (!localAddr.IsLoopback() && (!localAddr.IsRFC1918() || !addr.IsRFC1918()))
        addr = localAddr;
    }
  }
  return addr.IsValid();
}


PIPSocket::Address PIPSocket::GetRouteInterfaceAddress(PIPSocket::Address remoteAddress)
{
  PIPSocket::InterfaceTable hostInterfaceTable;
  PIPSocket::GetInterfaceTable(hostInterfaceTable);

  PIPSocket::RouteTable hostRouteTable;
  PIPSocket::GetRouteTable(hostRouteTable);

  if (hostInterfaceTable.IsEmpty())
    return PIPSocket::GetDefaultIpAny();

  for (PINDEX IfaceIdx = 0; IfaceIdx < hostInterfaceTable.GetSize(); IfaceIdx++) {
    if (remoteAddress == hostInterfaceTable[IfaceIdx].GetAddress()) {
      PTRACE(5, "PWLib\tRoute packet for " << remoteAddress
             << " over interface " << hostInterfaceTable[IfaceIdx].GetName()
             << "[" << hostInterfaceTable[IfaceIdx].GetAddress() << "]");
      return hostInterfaceTable[IfaceIdx].GetAddress();
    }
  }

  PIPSocket::RouteEntry * route = NULL;
  for (PINDEX routeIdx = 0; routeIdx < hostRouteTable.GetSize(); routeIdx++) {
    PIPSocket::RouteEntry & routeEntry = hostRouteTable[routeIdx];

    DWORD network = (DWORD) routeEntry.GetNetwork();
    DWORD mask = (DWORD) routeEntry.GetNetMask();

    if (((DWORD)remoteAddress & mask) == network) {
      if (route == NULL)
        route = &routeEntry;
      else if ((DWORD)routeEntry.GetNetMask() > (DWORD)route->GetNetMask())
        route = &routeEntry;
    }
  }

  if (route != NULL) {
    for (PINDEX IfaceIdx = 0; IfaceIdx < hostInterfaceTable.GetSize(); IfaceIdx++) {
      if (route->GetInterface() == hostInterfaceTable[IfaceIdx].GetName()) {
        PTRACE(5, "PWLib\tRoute packet for " << remoteAddress
               << " over interface " << hostInterfaceTable[IfaceIdx].GetName()
               << "[" << hostInterfaceTable[IfaceIdx].GetAddress() << "]");
        return hostInterfaceTable[IfaceIdx].GetAddress();
      }
    }
  }

  return PIPSocket::GetDefaultIpAny();
}

//////////////////////////////////////////////////////////////////////////////
// PTCPSocket

PTCPSocket::PTCPSocket(WORD newPort)
{
  SetPort(newPort);
}


PTCPSocket::PTCPSocket(const PString & service)
{
  SetPort(service);
}


PTCPSocket::PTCPSocket(const PString & address, WORD newPort)
{
  SetPort(newPort);
  Connect(address);
}


PTCPSocket::PTCPSocket(const PString & address, const PString & service)
{
  SetPort(service);
  Connect(address);
}


PTCPSocket::PTCPSocket(PSocket & socket)
{
  Accept(socket);
}


PTCPSocket::PTCPSocket(PTCPSocket & tcpSocket)
{
  Accept(tcpSocket);
}


PObject * PTCPSocket::Clone() const
{
  return new PTCPSocket(port);
}


// By default IPv4 only adresses
PBoolean PTCPSocket::OpenSocket()
{
  return ConvertOSError(os_handle = os_socket(AF_INET, SOCK_STREAM, 0));
}


// ipAdressFamily should be AF_INET or AF_INET6
PBoolean PTCPSocket::OpenSocket(int ipAdressFamily) 
{
  return ConvertOSError(os_handle = os_socket(ipAdressFamily, SOCK_STREAM, 0));
}


const char * PTCPSocket::GetProtocolName() const
{

⌨️ 快捷键说明

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