📄 sockets.cxx
字号:
} if (host->GetHostAddress() == 0) return NULL; return host;}BOOL PHostByAddr::GetHostName(const PIPSocket::Address & addr, PString & hostname){ PIPCacheData * host = GetHost(addr); if (host != NULL) { hostname = host->GetHostName(); hostname.MakeUnique(); } mutex.Signal(); return host != NULL;}BOOL PHostByAddr::GetHostAddress(const PIPSocket::Address & addr, PIPSocket::Address & address){ 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();#ifdef P_AIX struct hostent_data ht_data; struct hostent host_info;#else struct hostent * host_info;#endif int retry = 3; do {#if ( ( defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) ) || ( defined(__NUCLEUS_PLUS__) ) ) // 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! #ifndef P_AIX // that I get no warnings int localErrNo; char buffer[REENTRANT_BUFFER_LEN]; struct hostent hostEnt;#endif#ifdef P_LINUX ::gethostbyaddr_r((const char *)&addr, sizeof(addr), PF_INET, &hostEnt, buffer, REENTRANT_BUFFER_LEN, &host_info, &localErrNo);#elif P_AIX ::gethostbyaddr_r((char *)&addr, sizeof(addr), PF_INET, &host_info, &ht_data );#else host_info = ::gethostbyaddr_r((const char *)&addr, sizeof(addr), PF_INET, &hostEnt, buffer, REENTRANT_BUFFER_LEN, &localErrNo);#endif#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 } while (h_errno == TRY_AGAIN && --retry > 0); mutex.Wait(); if (retry == 0) return FALSE;#ifdef P_AIX host = new PIPCacheData(&host_info, inet_ntoa(addr));#else host = new PIPCacheData(host_info, inet_ntoa(addr));#endif SetAt(key, host); } if (host->GetHostAddress() == 0) return NULL; return host;}//////////////////////////////////////////////////////////////////////////////// PSocketPSocket::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, int level){ return ConvertOSError(::setsockopt(os_handle, level, option, (char *)&value, sizeof(value)));}BOOL PSocket::SetOption(int option, const void * valuePtr, PINDEX valueSize, int level){ return ConvertOSError(::setsockopt(os_handle, level, option, (char *)valuePtr, valueSize));}BOOL PSocket::GetOption(int option, int & value, int level){#ifdef __BEOS__ return FALSE;#else socklen_t valSize = sizeof(value); return ConvertOSError(::getsockopt(os_handle, level, option, (char *)&value, &valSize));#endif}BOOL PSocket::GetOption(int option, void * valuePtr, PINDEX valueSize, int level){#ifdef __BEOS__ return FALSE;#else return ConvertOSError(::getsockopt(os_handle, level, option, (char *)valuePtr, (socklen_t *)&valueSize));#endif}BOOL PSocket::Shutdown(ShutdownValue value){ return ConvertOSError(::shutdown(os_handle, value));}WORD PSocket::GetProtocolByName(const PString & name){#if !defined(__BEOS__) && !defined(__NUCLEUS_PLUS__) struct protoent * ent = getprotobyname(name); if (ent != NULL) return ent->p_proto;#endif return 0;}PString PSocket::GetNameByProtocol(WORD proto){#if !defined(__BEOS__) && !defined(__NUCLEUS_PLUS__) 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){#ifdef __NUCLEUS_PLUS__ if(!strcmp(protocol,"tcp") && service.AsInteger()>0) return service.AsInteger(); PAssertAlways ("PSocket::GetPortByService: problem as no ::getservbyname in Nucleus NET"); return 0;#else PINDEX space = service.FindOneOf(" \t\r\n"); struct servent * serv = ::getservbyname(service(0, space-1), protocol); if (serv != NULL) return ntohs(serv->s_port); 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;#endif}PString PSocket::GetServiceByPort(WORD port) const{ return GetServiceByPort(GetProtocolName(), port);}PString PSocket::GetServiceByPort(const char * protocol, WORD port){#if !defined(__BEOS__) && !defined(__NUCLEUS_PLUS__) 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;}//////////////////////////////////////////////////////////////////////////////// PIPSocketPIPSocket::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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -