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

📄 sockets.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:
void PSocket::SetPort(const PString & service)
{
  PAssert(!IsOpen(), "Cannot change port number of opened socket");
  port = GetPortByService(service);
}


WORD PSocket::GetPort() const
{
  return port;
}


PString PSocket::GetService() const
{
  return GetServiceByPort(port);
}


int PSocket::Select(PSocket & sock1, PSocket & sock2)
{
  return Select(sock1, sock2, PMaxTimeInterval);
}


int PSocket::Select(PSocket & sock1,
                    PSocket & sock2,
                    const PTimeInterval & timeout)
{
  if (!sock1.IsOpen() || !sock2.IsOpen())
    return NotOpen;

  int h1 = sock1.GetHandle();
  int h2 = sock2.GetHandle();

#ifdef _MSC_VER
#pragma warning(disable:4127)
#endif
  fd_set readfds;
  FD_ZERO(&readfds);
  FD_SET(h1, &readfds);
  FD_SET(h2, &readfds);
  fd_set writefds;
  FD_ZERO(&writefds);
  fd_set exceptfds;
  FD_ZERO(&exceptfds);
#ifdef _MSC_VER
#pragma warning(default:4127)
#endif

  PIntArray allfds(4);
  allfds[0] = h1;
  allfds[1] = 1;
  allfds[2] = h2;
  allfds[3] = 1;
  int rval = os_select(PMAX(h1, h2)+1,
                                readfds, writefds, exceptfds, allfds, timeout);

  Errors lastError;
  int osError;
  if (!ConvertOSError(rval, lastError, osError))
    return lastError;

  rval = 0;
  if (FD_ISSET(h1, &readfds))
    rval -= 1;
  if (FD_ISSET(h2, &readfds))
    rval -= 2;

  return rval;
}


PChannel::Errors PSocket::Select(SelectList & read)
{
  SelectList dummy1, dummy2;
  return Select(read, dummy1, dummy2, PMaxTimeInterval);
}


PChannel::Errors PSocket::Select(SelectList & read, const PTimeInterval & timeout)
{
  SelectList dummy1, dummy2;
  return Select(read, dummy1, dummy2, timeout);
}


PChannel::Errors PSocket::Select(SelectList & read, SelectList & write)
{
  SelectList dummy1;
  return Select(read, write, dummy1, PMaxTimeInterval);
}


PChannel::Errors PSocket::Select(SelectList & read,
                                 SelectList & write,
                                 const PTimeInterval & timeout)
{
  SelectList dummy1;
  return Select(read, write, dummy1, timeout);
}


PChannel::Errors PSocket::Select(SelectList & read,
                                 SelectList & write,
                                 SelectList & except)
{
  return Select(read, write, except, PMaxTimeInterval);
}


PChannel::Errors PSocket::Select(SelectList & read,
                                 SelectList & write,
                                 SelectList & except,
                                 const PTimeInterval & timeout)
{
  int maxfds = 0;
  PINDEX nextfd = 0;
  PIntArray allfds(2*(read.GetSize()+write.GetSize()+except.GetSize()));

#ifdef _MSC_VER
#pragma warning(disable:4127)
#endif
  fd_set readfds;
  FD_ZERO(&readfds);
  PINDEX i;
  for (i = 0; i < read.GetSize(); i++) {
    if (!read[i].IsOpen())
      return NotOpen;
    int h = read[i].GetHandle();
    FD_SET(h, &readfds);
    if (h > maxfds)
      maxfds = h;
    allfds[nextfd++] = h;
    allfds[nextfd++] = 1;
  }

  fd_set writefds;
  FD_ZERO(&writefds);
  for (i = 0; i < write.GetSize(); i++) {
    if (!write[i].IsOpen())
      return NotOpen;
    int h = write[i].GetHandle();
    FD_SET(h, &writefds);
    if (h > maxfds)
      maxfds = h;
    allfds[nextfd++] = h;
    allfds[nextfd++] = 2;
  }

  fd_set exceptfds;
  FD_ZERO(&exceptfds);
  for (i = 0; i < except.GetSize(); i++) {
    if (!except[i].IsOpen())
      return NotOpen;
    int h = except[i].GetHandle();
    FD_SET(h, &exceptfds);
    if (h > maxfds)
      maxfds = h;
    allfds[nextfd++] = h;
    allfds[nextfd++] = 4;
  }
#ifdef _MSC_VER
#pragma warning(default:4127)
#endif

  int retval = os_select(maxfds+1,readfds,writefds,exceptfds,allfds,timeout);

  Errors lastError;
  int osError;
  if (!ConvertOSError(retval, lastError, osError))
    return lastError;

  if (retval > 0) {
    for (i = 0; i < read.GetSize(); i++) {
      int h = read[i].GetHandle();
      if (h < 0)
        return Interrupted;
      if (!FD_ISSET(h, &readfds))
        read.RemoveAt(i--);
    }
    for (i = 0; i < write.GetSize(); i++) {
      int h = write[i].GetHandle();
      if (h < 0)
        return Interrupted;
      if (!FD_ISSET(h, &writefds))
        write.RemoveAt(i--);
    }
    for (i = 0; i < except.GetSize(); i++) {
      int h = except[i].GetHandle();
      if (h < 0)
        return Interrupted;
      if (!FD_ISSET(h, &exceptfds))
        except.RemoveAt(i--);
    }
  }
  else {
    read.RemoveAll();
    write.RemoveAll();
    except.RemoveAll();
  }

  return NoError;
}



//////////////////////////////////////////////////////////////////////////////
// PIPSocket

PIPSocket::PIPSocket()
{
}


void PIPSocket::ClearNameCache()
{
  pHostByName().mutex.Wait();
  pHostByAddr().mutex.Wait();
  pHostByName().RemoveAll();
  pHostByAddr().RemoveAll();
#if (defined(_WIN32) || defined(WINDOWS)) && !defined(__NUCLEUS_MNT__) // Kludge to avoid strange NT bug
  static PTimeInterval delay = GetConfigTime("NT Bug Delay", 0);
  if (delay != 0) {
    ::Sleep(delay.GetInterval());
    ::gethostbyname("www.microsoft.com");
  }
#endif
  pHostByName().mutex.Signal();
  pHostByAddr().mutex.Signal();
}


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


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;

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

  return addr;
}


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


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

  // lookup the host address using inet_addr, assuming it is a "." address
  addr = hostname;
  if (addr != 0)
    return TRUE;

  // 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;
}


BOOL PIPSocket::GetLocalAddress(Address & addr)
{
  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (!ConvertOSError(::getsockname(os_handle,(struct sockaddr*)&address,&size)))
    return FALSE;

  addr = address.sin_addr;
  return TRUE;
}


BOOL PIPSocket::GetLocalAddress(Address & addr, WORD & portNum)
{
  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (!ConvertOSError(::getsockname(os_handle,(struct sockaddr*)&address,&size)))
    return FALSE;

  addr = address.sin_addr;
  portNum = ntohs(address.sin_port);
  return TRUE;
}
 
BOOL PIPSocket::GetPeerAddress(Address & addr)
{
  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (!ConvertOSError(::getpeername(os_handle,(struct sockaddr*)&address,&size)))
    return FALSE;

  addr = address.sin_addr;
  return TRUE;
}


BOOL PIPSocket::GetPeerAddress(Address & addr, WORD & portNum)
{
  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (!ConvertOSError(::getpeername(os_handle,(struct sockaddr*)&address,&size)))
    return FALSE;

  addr = address.sin_addr;
  portNum = ntohs(address.sin_port);
  return TRUE;
}


PString PIPSocket::GetLocalHostName()
{
  PString name;

  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (ConvertOSError(::getsockname(os_handle, (struct sockaddr *)&address, &size)))
    name = GetHostName(address.sin_addr);

  return name;
}


PString PIPSocket::GetPeerHostName()
{
  PString name;

  sockaddr_in address;
  socklen_t size = sizeof(address);
  if (ConvertOSError(::getpeername(os_handle, (struct sockaddr *)&address, &size)))
    name = GetHostName(address.sin_addr);

  return name;
}


BOOL PIPSocket::Connect(const PString & host)
{
  Address ipnum;
  if (GetHostAddress(host, ipnum))
    return Connect(INADDR_ANY, 0, ipnum);
  return FALSE;
}


BOOL PIPSocket::Connect(const Address & addr)
{
  return Connect(INADDR_ANY, 0, addr);
}


BOOL PIPSocket::Connect(WORD localPort, const Address & addr)
{
  return Connect(INADDR_ANY, localPort, addr);
}


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


BOOL 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");

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

  // attempt to connect
  sockaddr_in sin;
  if (localPort != 0 || iface != INADDR_ANY) {
    if (!SetOption(SO_REUSEADDR, 1)) {
      os_close();
      return FALSE;
    }
    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 FALSE;
    }
  }

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

  os_close();
  return FALSE;
}

⌨️ 快捷键说明

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