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

📄 sockets.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 5 页
字号:
#else

  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (getpeername(os_handle, (struct sockaddr *)&address, &size) == 0)
    return GetHostName(address.sin_addr) + psprintf(":%u", ntohs(address.sin_port));

#endif

  return PString::Empty();
}


PString PIPSocket::GetHostName()
{
  char name[100];
  if (gethostname(name, sizeof(name)-1) != 0)
    return "localhost";
  name[sizeof(name)-1] = '\0';
  return name;
}


PString PIPSocket::GetHostName(const PString & hostname)
{
  // lookup the host address using inet_addr, assuming it is a "." address
  Address temp = hostname;
  if (temp != 0)
    return GetHostName(temp);

  PString canonicalname;
  if (pHostByName().GetHostName(hostname, canonicalname))
    return canonicalname;

  return hostname;
}


PString PIPSocket::GetHostName(const Address & addr)
{
  if (addr == 0)
    return addr.AsString();

  PString hostname;
  if (pHostByAddr().GetHostName(addr, hostname))
    return hostname;

  return addr.AsString();
}


PBoolean PIPSocket::GetHostAddress(Address & addr)
{
  return pHostByName().GetHostAddress(GetHostName(), addr);
}


PBoolean PIPSocket::GetHostAddress(const PString & hostname, Address & addr)
{
  if (hostname.IsEmpty())
    return PFalse;

  // Check for special case of "[ipaddr]"
  if (hostname[0] == '[') {
    PINDEX end = hostname.Find(']');
    if (end != P_MAX_INDEX) {
      if (addr.FromString(hostname(1, end-1)))
        return PTrue;
    }
  }

  // Assuming it is a "." address and return if so
  if (addr.FromString(hostname))
    return PTrue;

  // otherwise lookup the name as a host name
  return pHostByName().GetHostAddress(hostname, addr);
}


PStringArray PIPSocket::GetHostAliases(const PString & hostname)
{
  PStringArray aliases;

  // lookup the host address using inet_addr, assuming it is a "." address
  Address addr = hostname;
  if (addr != 0)
    pHostByAddr().GetHostAliases(addr, aliases);
  else
    pHostByName().GetHostAliases(hostname, aliases);

  return aliases;
}


PStringArray PIPSocket::GetHostAliases(const Address & addr)
{
  PStringArray aliases;

  pHostByAddr().GetHostAliases(addr, aliases);

  return aliases;
}


PString PIPSocket::GetLocalAddress()
{
  PStringStream str;
  Address addr;
  WORD port;
  if (GetLocalAddress(addr, port))
    str << addr << ':' << port;
  return str;
}


PBoolean PIPSocket::GetLocalAddress(Address & addr)
{
  WORD dummy;
  return GetLocalAddress(addr, dummy);
}


PBoolean PIPSocket::GetLocalAddress(Address & addr, WORD & portNum)
{
#if P_HAS_IPV6
  Address   addrv4;
  Address   peerv4;
  Psockaddr sa;
  socklen_t size = sa.GetSize();
  if (!ConvertOSError(::getsockname(os_handle, sa, &size)))
    return PFalse;

  addr = sa.GetIP();
  portNum = sa.GetPort();

  // If the remote host is an IPv4 only host and our interface if an IPv4/IPv6 mapped
  // Then return an IPv4 address instead of an IPv6
  if (GetPeerAddress(peerv4)) {
    if ((peerv4.GetVersion()==4)||(peerv4.IsV4Mapped())) {
      if (addr.IsV4Mapped()) {
        addr = Address(addr[12], addr[13], addr[14], addr[15]);
      }
    }
  }
  
#else

  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (!ConvertOSError(::getsockname(os_handle,(struct sockaddr*)&address,&size)))
    return PFalse;

  addr = address.sin_addr;
  portNum = ntohs(address.sin_port);

#endif

  return PTrue;
}


PString PIPSocket::GetPeerAddress()
{
  PStringStream str;
  Address addr;
  WORD port;
  if (GetPeerAddress(addr, port))
    str << addr << ':' << port;
  return str;
}


PBoolean PIPSocket::GetPeerAddress(Address & addr)
{
  WORD portNum;
  return GetPeerAddress(addr, portNum);
}

PBoolean PIPSocket::GetPeerAddress(Address & addr, WORD & portNum)
{
#if P_HAS_IPV6

  Psockaddr sa;
  socklen_t size = sa.GetSize();
  if (!ConvertOSError(::getpeername(os_handle, sa, &size)))
    return PFalse;

  addr = sa.GetIP();
  portNum = sa.GetPort();

#else

  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (!ConvertOSError(::getpeername(os_handle,(struct sockaddr*)&address,&size)))
    return PFalse;

  addr = address.sin_addr;
  portNum = ntohs(address.sin_port);

#endif

  return PTrue;
}


PString PIPSocket::GetLocalHostName()
{
  Address addr;

  if (GetLocalAddress(addr))
    return GetHostName(addr);

  return PString::Empty();
}


PString PIPSocket::GetPeerHostName()
{
  Address addr;

  if (GetPeerAddress(addr))
    return GetHostName(addr);

  return PString::Empty();
}


PBoolean PIPSocket::Connect(const PString & host)
{
  Address ipnum(host);
#if P_HAS_IPV6
  if (ipnum.IsValid() || GetHostAddress(host, ipnum))
    return Connect(GetDefaultIpAny(), 0, ipnum);
#else
  if (ipnum.IsValid() || GetHostAddress(host, ipnum))
    return Connect(INADDR_ANY, 0, ipnum);
#endif  
  return PFalse;
}


PBoolean PIPSocket::Connect(const Address & addr)
{
#if P_HAS_IPV6
  return Connect(GetDefaultIpAny(), 0, addr);
#else
  return Connect(INADDR_ANY, 0, addr);
#endif
}


PBoolean PIPSocket::Connect(WORD localPort, const Address & addr)
{
#if P_HAS_IPV6
  return Connect(GetDefaultIpAny(), localPort, addr);
#else
  return Connect(INADDR_ANY, localPort, addr);
#endif
}


PBoolean PIPSocket::Connect(const Address & iface, const Address & addr)
{
  return Connect(iface, 0, addr);
}


PBoolean PIPSocket::Connect(const Address & iface, WORD localPort, const Address & addr)
{
  // close the port if it is already open
  if (IsOpen())
    Close();

  // make sure we have a port
  PAssert(port != 0, "Cannot connect socket without setting port");

#if P_HAS_IPV6

  Psockaddr sa(addr, port);

  // attempt to create a socket with the right family
  if (!OpenSocket(sa->sa_family))
    return PFalse;

  if (localPort != 0 || iface.IsValid()) {
    Psockaddr bind_sa(iface, localPort);

    if (!SetOption(SO_REUSEADDR, 0)) {
      os_close();
      return PFalse;
    }
    
    if (!ConvertOSError(::bind(os_handle, bind_sa, bind_sa.GetSize()))) {
      os_close();
      return PFalse;
    }
  }
  
  // attempt to connect
  if (os_connect(sa, sa.GetSize()))
    return PTrue;
  
#else

  // attempt to create a socket
  if (!OpenSocket())
    return PFalse;

  // attempt to connect
  sockaddr_in sin;
  if (localPort != 0 || iface.IsValid()) {
    if (!SetOption(SO_REUSEADDR, 0)) {
      os_close();
      return PFalse;
    }
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = iface;
    sin.sin_port        = htons(localPort);       // set the port
    if (!ConvertOSError(::bind(os_handle, (struct sockaddr*)&sin, sizeof(sin)))) {
      os_close();
      return PFalse;
    }
  }

  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_port   = htons(port);  // set the port
  sin.sin_addr   = addr;
  if (os_connect((struct sockaddr *)&sin, sizeof(sin)))
    return PTrue;

#endif

  os_close();
  return PFalse;
}


PBoolean PIPSocket::Listen(unsigned queueSize, WORD newPort, Reusability reuse)
{
#if P_HAS_IPV6
  return Listen(GetDefaultIpAny(), queueSize, newPort, reuse);
#else
  return Listen(INADDR_ANY, queueSize, newPort, reuse);
#endif
}


PBoolean PIPSocket::Listen(const Address & bindAddr,
                       unsigned,
                       WORD newPort,
                       Reusability reuse)
{
  // make sure we have a port
  if (newPort != 0)
    port = newPort;

#if P_HAS_IPV6
  Psockaddr bind_sa(bindAddr, port); 

  if (IsOpen()) {
    int socketType;
    if (!GetOption(SO_TYPE, socketType, SOL_SOCKET) || bind_sa->sa_family != socketType)
      Close();
  }
#endif

  if (!IsOpen()) {
    // attempt to create a socket
#if P_HAS_IPV6
    if (!OpenSocket(bind_sa->sa_family))
      return PFalse;
#else
    if (!OpenSocket())
      return PFalse;
#endif
  }
  
#ifndef __BEOS__
  // attempt to listen
  if (!SetOption(SO_REUSEADDR, reuse == CanReuseAddress ? 1 : 0)) {
    os_close();
    return PFalse;
  }
#else
  // attempt to listen
  int value = reuse == CanReuseAddress ? 1 : 0;
  if (!SetOption(SO_REUSEADDR, &value, sizeof(int))) {
    os_close();
    return PFalse;
  }
#endif // BEOS

#if P_HAS_IPV6

  if (ConvertOSError(::bind(os_handle, bind_sa, bind_sa.GetSize()))) {
    Psockaddr sa;
    socklen_t size = sa.GetSize();
    if (!ConvertOSError(::getsockname(os_handle, sa, &size)))
      return PFalse;

    port = sa.GetPort();
    return PTrue;
  }

#else

  // attempt to listen
  sockaddr_in sin;
  memset(&sin, 0, sizeof(sin));
  sin.sin_family      = AF_INET;
  sin.sin_addr.s_addr = bindAddr;
  sin.sin_port        = htons(port);       // set the port

#ifdef __NUCLEUS_NET__
  int bind_result;
  if (port == 0)
    bind_result = ::bindzero(os_handle, (struct sockaddr*)&sin, sizeof(sin));
  else
    bind_result = ::bind(os_handle, (struct sockaddr*)&sin, sizeof(sin));
  if (ConvertOSError(bind_result))
#else
  if (ConvertOSError(::bind(os_handle, (struct sockaddr*)&sin, sizeof(sin))))
#endif
  {
    socklen_t size = sizeof(sin);
    if (ConvertOSError(::getsockname(os_handle, (struct sockaddr*)&sin, &size))) {
      port = ntohs(sin.sin_port);
      return PTrue;
    }
  }

#endif

  os_close();
  return PFalse;
}


const PIPSocket::Address & PIPSocket::Address::GetLoopback()
{
  return loopback4;
}


#if P_HAS_IPV6

/// Check for v4 mapped i nv6 address ::ffff:a.b.c.d
PBoolean PIPSocket::Address::IsV4Mapped() const
{
  if (version != 6)
    return PFalse;
  return IN6_IS_ADDR_V4MAPPED(&v.six) || IN6_IS_ADDR_V4COMPAT(&v.six);
}


const PIPSocket::Address & PIPSocket::Address::GetLoopback6()
{
  return loopback6;
}


const PIPSocket::Address & PIPSocket::Address::GetAny6()
{
  return any6;
}

#endif


PBoolean PIPSocket::Address::IsAny() const
{
  return (!IsValid());
}


const PIPSocket::Address & PIPSocket::Address::GetBroadcast()
{
  return broadcast4;
}


PIPSocket::Address::Address()
{
  *this = loopback4;
}


PIPSocket::Address::Address(const PString & dotNotation)
{
  operator=(dotNotation);
}


PIPSocket::Address::Address(PINDEX len, const BYTE * bytes)
{
  switch (len) {
#if P_HAS_IPV6
    case 16 :
      version = 6;
      memcpy(&v.six, bytes, len);
      break;
#endif
    case 4 :
      version = 4;
      memcpy(&v.four, bytes, len);
      break;

    default :
      version = 0;
  }
}


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


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

// Create an IP (v4 or v6) address from a sockaddr (sockaddr_in, sockaddr_in6 or sockaddr_in6_old) structure
PIPSocket::Address::Address(const int ai_family, const int ai_addrlen, struct sockaddr *ai_addr)
{
  switch (ai_family) {
#if P_HAS_IPV6
    case AF_INET6:
      if (ai_addrlen < (int)sizeof(sockaddr_in6))
        break;

      version = 6;
      v.six = ((struct sockaddr_in6 *)ai_addr)->sin6_addr;

⌨️ 快捷键说明

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