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

📄 sockets.cxx

📁 基于VXWORKS H323通信技术源代码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
  PIPCacheData * host = GetHost(addr);

  if (host != NULL)
    address = host->GetHostAddress();

  mutex.Signal();
  return host != NULL;
}


BOOL PHostByAddr::GetHostAliases(const PIPSocket::Address & addr, PStringArray & aliases)
{
  PIPCacheData * host = GetHost(addr);

  if (host != NULL) {
    const PStringList & a = host->GetHostAliases();
    aliases.SetSize(a.GetSize());
    for (PINDEX i = 0; i < a.GetSize(); i++)
      aliases[i] = a[i];
  }

  mutex.Signal();
  return host != NULL;
}

PIPCacheData * PHostByAddr::GetHost(const PIPSocket::Address & addr)
{
  mutex.Wait();

  PIPCacheKey key = addr;
  PIPCacheData * host = GetAt(key);

  if (host != NULL && host->HasAged()) {
    SetAt(key, NULL);
    host = NULL;
  }

  if (host == NULL) {
    mutex.Signal();

    struct hostent * host_info;
    int retry = 3;
    do {
	#if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB)
	      // this function should really be a static on PIPSocket, but this would
	      // require allocating thread-local storage for the data and that's too much
	      // of a pain!
	      struct hostent hostEnt;
	      int localErrNo;
	      char buffer[REENTRANT_BUFFER_LEN];
	
		#ifdef P_LINUX
		      ::gethostbyaddr_r((const char *)&addr, sizeof(addr),
		                        PF_INET, 
		                        &hostEnt,
	 	                       buffer, REENTRANT_BUFFER_LEN,
	  	                      &host_info,
	   	                     &localErrNo);
		#else
		      host_info = ::gethostbyaddr_r((const char *)&addr, sizeof(addr), PF_INET, 
		                                    &hostEnt, buffer, REENTRANT_BUFFER_LEN, &localErrNo);
		#endif
		
	#elif defined (P_VXWORKS)
		char buffer[1024];	
	// added by Jurjan
		host_info = ::resolvGetHostByAddr((const char *)&addr, buffer, 1024);

	#else
	      host_info = ::gethostbyaddr((const char *)&addr, sizeof(addr), PF_INET);
		#if defined(_WIN32) || defined(WINDOWS)  // Kludge to avoid strange 95 bug
		      extern P_IsOldWin95();
	 	      if (P_IsOldWin95() && host_info != NULL && host_info->h_addr_list[0] != NULL)
	        	host_info->h_addr_list[1] = NULL;
		#endif
	#endif	// added by Jurjan
    } while (errno == S_resolvLib_TRY_AGAIN && --retry > 0);  //(h_errno == TRY_AGAIN && --retry > 0);

    mutex.Wait();

    if (retry == 0)
      return FALSE;

    host = new PIPCacheData(host_info, inet_ntoa(addr.s_addr));

    SetAt(key, host);
  }

  if (host->GetHostAddress() == 0)
    return NULL;


  return host;
}


//////////////////////////////////////////////////////////////////////////////
// PSocket

PSocket::PSocket()
{
  port = 0;
}


BOOL PSocket::Connect(const PString &)
{
  PAssertAlways("Illegal operation.");
  return FALSE;
}


BOOL PSocket::Listen(unsigned, WORD, Reusability)
{
  PAssertAlways("Illegal operation.");
  return FALSE;
}


BOOL PSocket::Accept(PSocket &)
{
  PAssertAlways("Illegal operation.");
  return FALSE;
}


BOOL PSocket::SetOption(int option, int value)
{
  return ConvertOSError(::setsockopt(os_handle,
                           SOL_SOCKET, option, (char *)&value, sizeof(value)));
}


BOOL PSocket::SetOption(int option, const void * valuePtr, PINDEX valueSize)
{
  return ConvertOSError(::setsockopt(os_handle,
                             SOL_SOCKET, option, (char *)valuePtr, valueSize));
}


BOOL PSocket::GetOption(int option, int & value)
{
#ifdef __BEOS__
  return FALSE;
#else
  socklen_t valSize = sizeof(value);
  return ConvertOSError(::getsockopt(os_handle,
                                SOL_SOCKET, option, (char *)&value, (int *)(unsigned int *)&valSize)); // casted by Jurjan
#endif
}


BOOL PSocket::GetOption(int option, void * valuePtr, PINDEX valueSize)
{
#ifdef __BEOS__
  return FALSE;
#else
  return ConvertOSError(::getsockopt(os_handle,
                            SOL_SOCKET, option, (char *)valuePtr, (int *)(unsigned int *)(socklen_t *)&valueSize));	// casted by Jurjan
#endif
}


BOOL PSocket::Shutdown(ShutdownValue value)
{
  return ConvertOSError(::shutdown(os_handle, value));
}


WORD PSocket::GetProtocolByName(const PString & name)
{
#if !defined(__BEOS__) && !defined(P_VXWORKS)	// added by Jurjan   todo
  struct protoent * ent = getprotobyname(name);
  if (ent != NULL)
    return ent->p_proto;
#endif
		PAssertAlways(PUnimplementedFunction);
  return 0;
}


PString PSocket::GetNameByProtocol(WORD proto)
{
#if !defined(__BEOS__) && !defined(P_VXWORKS)	// added by Jurjan    todo
  struct protoent * ent = getprotobynumber(proto);
  if (ent != NULL)
    return ent->p_name;
#endif

  return psprintf("%u", proto);
}


WORD PSocket::GetPortByService(const PString & serviceName) const
{
  return GetPortByService(GetProtocolName(), serviceName);
}


WORD PSocket::GetPortByService(const char * protocol, const PString & service)
{
  PINDEX space = service.FindOneOf(" \t\r\n");
#ifndef P_VXWORKS	// added by Jurjan.. todo..  getservbyname not implemented in VxWorks

  struct servent * serv = ::getservbyname(service(0, space-1), protocol);
  if (serv != NULL)
    return ntohs(serv->s_port);

		// add here

#endif	// !VXWORKS

  long portNum;
  if (space != P_MAX_INDEX)
    portNum = atol(service(space+1, P_MAX_INDEX));
  else if (isdigit(service[0]))
    portNum = atoi(service);
  else
    portNum = -1;

  if (portNum < 0 || portNum > 65535)
    return 0;


  return (WORD)portNum;
}


PString PSocket::GetServiceByPort(WORD port) const
{
  return GetServiceByPort(GetProtocolName(), port);
}


PString PSocket::GetServiceByPort(const char * protocol, WORD port)
{
#if !defined(__BEOS__) && !defined(P_VXWORKS) 	// added by Jurjan	todo
  struct servent * serv = ::getservbyport(htons(port), protocol);
  if (serv != NULL)
    return PString(serv->s_name);
  else
#endif
    return PString(PString::Unsigned, port);
}


void PSocket::SetPort(WORD newPort)
{
  PAssert(!IsOpen(), "Cannot change port number of opened socket");
  port = newPort;
}


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) // 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, (int *)(unsigned int *)&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)
{

⌨️ 快捷键说明

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