📄 sockets.cxx
字号:
BOOL PIPCacheData::HasAged() const{ static PTimeInterval retirement = GetConfigTime("Age Limit", 300000); // 5 minutes PTime now; PTimeInterval age = now - birthDate; return age > retirement;}BOOL PHostByName::GetHostName(const PString & name, PString & hostname){ PIPCacheData * host = GetHost(name); if (host != NULL) { hostname = host->GetHostName(); hostname.MakeUnique(); } mutex.Signal(); return host != NULL;}BOOL PHostByName::GetHostAddress(const PString & name, PIPSocket::Address & address){ PIPCacheData * host = GetHost(name); if (host != NULL) address = host->GetHostAddress(); mutex.Signal(); return host != NULL;}BOOL PHostByName::GetHostAliases(const PString & name, PStringArray & aliases){ PIPCacheData * host = GetHost(name); 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 * PHostByName::GetHost(const PString & name){ mutex.Wait(); PCaselessString key = name; PIPCacheData * host = GetAt(key); int localErrNo = NETDB_SUCCESS; if (host != NULL && host->HasAged()) { SetAt(key, NULL); host = NULL; } if (host == NULL) { mutex.Signal();#if P_HAS_IPV6 struct addrinfo *res; struct addrinfo hints = { AI_CANONNAME, PF_UNSPEC }; localErrNo = getaddrinfo((const char *)name, NULL , &hints, &res); mutex.Wait(); if (localErrNo != NETDB_SUCCESS) return NULL; host = new PIPCacheData(res, name); freeaddrinfo(res);#else // P_HAS_IPV6 int retry = 3; struct hostent * host_info;#ifdef P_AIX struct hostent_data ht_data; memset(&ht_data, 0, sizeof(ht_data)); struct hostent hostEnt; do { host_info = &hostEnt; ::gethostbyname_r(name, host_info, &ht_data); localErrNo = h_errno; } while (localErrNo == TRY_AGAIN && --retry > 0);#elif defined(P_RTEMS) || defined(P_CYGWIN) host_info = ::gethostbyname(name); localErrNo = h_errno;#elif defined P_VXWORKS struct hostent hostEnt; host_info = Vx_gethostbyname((char *)name, &hostEnt); localErrNo = h_errno;#elif defined P_LINUX char buffer[REENTRANT_BUFFER_LEN]; struct hostent hostEnt; do { if (::gethostbyname_r(name, &hostEnt, buffer, REENTRANT_BUFFER_LEN, &host_info, &localErrNo) == 0) localErrNo = NETDB_SUCCESS; } while (localErrNo == TRY_AGAIN && --retry > 0);#elif (defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB)) || defined(__NUCLEUS_PLUS__) char buffer[REENTRANT_BUFFER_LEN]; struct hostent hostEnt; do { host_info = ::gethostbyname_r(name, &hostEnt, buffer, REENTRANT_BUFFER_LEN, &localErrNo); } while (localErrNo == TRY_AGAIN && --retry > 0);#else host_info = ::gethostbyname(name); localErrNo = h_errno;#endif mutex.Wait(); if (localErrNo != NETDB_SUCCESS || retry == 0) return NULL; host = new PIPCacheData(host_info, name);#endif //P_HAS_IPV6 SetAt(key, host); } 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(); int retry = 3; int localErrNo = NETDB_SUCCESS; struct hostent * host_info;#ifdef P_AIX struct hostent_data ht_data; struct hostent hostEnt; do { host_info = &hostEnt; ::gethostbyaddr_r((char *)addr.GetPointer(), addr.GetSize(), PF_INET, host_info, &ht_data); localErrNo = h_errno; } while (localErrNo == TRY_AGAIN && --retry > 0);#elif defined P_RTEMS || defined P_CYGWIN host_info = ::gethostbyaddr(addr.GetPointer(), addr.GetSize(), PF_INET); localErrNo = h_errno;#elif defined P_VXWORKS struct hostent hostEnt; host_info = Vx_gethostbyaddr(addr.GetPointer(), &hostEnt);#elif defined P_LINUX char buffer[REENTRANT_BUFFER_LEN]; struct hostent hostEnt; do { ::gethostbyaddr_r(addr.GetPointer(), addr.GetSize(), PF_INET, &hostEnt, buffer, REENTRANT_BUFFER_LEN, &host_info, &localErrNo); } while (localErrNo == TRY_AGAIN && --retry > 0);#elif (defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB)) || defined(__NUCLEUS_PLUS__) char buffer[REENTRANT_BUFFER_LEN]; struct hostent hostEnt; do { host_info = ::gethostbyaddr_r(addr.GetPointer(), addr.GetSize(), PF_INET, &hostEnt, buffer, REENTRANT_BUFFER_LEN, &localErrNo); } while (localErrNo == TRY_AGAIN && --retry > 0);#else host_info = ::gethostbyaddr(addr.GetPointer(), addr.GetSize(), PF_INET); localErrNo = h_errno;#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 mutex.Wait(); if (localErrNo != NETDB_SUCCESS || retry == 0) return NULL; host = new PIPCacheData(host_info, addr.AsString()); SetAt(key, host); } if (host->GetHostAddress() == 0) return NULL; return host;}//////////////////////////////////////////////////////////////////////////////// P_fd_set#ifdef _MSC_VER#pragma warning(push)#pragma warning(disable:4127)#endifP_fd_set::P_fd_set(){ Construct(); Zero();}P_fd_set::P_fd_set(SOCKET fd){ Construct(); Zero(); FD_SET(fd, set);}P_fd_set & P_fd_set::operator=(SOCKET fd){ PAssert(fd < max_fd, PInvalidParameter); Zero(); FD_SET(fd, set); return *this;}P_fd_set & P_fd_set::operator+=(SOCKET fd){ PAssert(fd < max_fd, PInvalidParameter); FD_SET(fd, set); return *this;}P_fd_set & P_fd_set::operator-=(SOCKET fd){ PAssert(fd < max_fd, PInvalidParameter); FD_CLR(fd, set); return *this;}#ifdef _MSC_VER#pragma warning(pop)#endif//////////////////////////////////////////////////////////////////////////////// P_timevalP_timeval::P_timeval(){ tval.tv_usec = 0; tval.tv_sec = 0; infinite = FALSE;}P_timeval & P_timeval::operator=(const PTimeInterval & time){ infinite = time == PMaxTimeInterval; tval.tv_usec = (long)(time.GetMilliSeconds()%1000)*1000; tval.tv_sec = time.GetSeconds(); return *this;}//////////////////////////////////////////////////////////////////////////////// PSocketPSocket::PSocket(){ port = 0;#if P_HAS_RECVMSG catchReceiveToAddr = FALSE;#endif}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){#ifdef _WIN32_WCE if(option == SO_RCVBUF || option == SO_SNDBUF || option == IP_TOS) return TRUE;#endif 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){ socklen_t valSize = sizeof(value); return ConvertOSError(::getsockopt(os_handle, level, option, (char *)&value, &valSize));}BOOL PSocket::GetOption(int option, void * valuePtr, PINDEX valueSize, int level){ return ConvertOSError(::getsockopt(os_handle, level, option, (char *)valuePtr, (socklen_t *)&valueSize));}BOOL PSocket::Shutdown(ShutdownValue value){ return ConvertOSError(::shutdown(os_handle, value));}WORD PSocket::GetProtocolByName(const PString & name){#if !defined(__NUCLEUS_PLUS__) && !defined(_WIN32_WCE) && !defined(P_VXWORKS) struct protoent * ent = getprotobyname(name); if (ent != NULL) return ent->p_proto;#endif return 0;}PString PSocket::GetNameByProtocol(WORD proto){#if !defined(__NUCLEUS_PLUS__) && !defined(_WIN32_WCE) && !defined(P_VXWORKS) 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){ // if the string is a valid integer, then use integer value // this avoids stupid problems like operating systems that match service // names to substrings (like "2000" to "taskmaster2000") if (strspn(service, "0123456789") == strlen(service)) return (WORD)service.AsUnsigned();#if defined( __NUCLEUS_PLUS__ ) PAssertAlways("PSocket::GetPortByService: problem as no ::getservbyname in Nucleus NET"); return 0;#elif defined(_WIN32_WCE) PAssertAlways("PSocket::GetPortByService: problem for WindowsCE as no port given."); return 0;#elif defined(P_VXWORKS) PAssertAlways("PSocket::GetPortByService: problem as no ::getservbyname in VxWorks"); 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(__NUCLEUS_PLUS__) && !defined(_WIN32_WCE) && !defined(P_VXWORKS) struct servent * serv = ::getservbyport(htons(port), protocol);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -