📄 sockets.cxx
字号:
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){ SelectList read, dummy1, dummy2; read += sock1; read += sock2; Errors lastError; int osError; if (!ConvertOSError(Select(read, dummy1, dummy2, timeout), lastError, osError)) return lastError; switch (read.GetSize()) { case 0 : return 0; case 2 : return -3; default : return &read[0] == &sock1 ? -1 : -2; }}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);}//////////////////////////////////////////////////////////////////////////////// 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{#if P_HAS_IPV6 Psockaddr sa; socklen_t size = sa.GetSize(); if (getpeername(os_handle, sa, &size) == 0) return GetHostName(sa.GetIP()) + psprintf(":%u", sa.GetPort());#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();}BOOL PIPSocket::GetHostAddress(Address & addr){ return pHostByName().GetHostAddress(GetHostName(), addr);}BOOL PIPSocket::GetHostAddress(const PString & hostname, Address & addr){ if (hostname.IsEmpty()) return FALSE; // 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 TRUE; } } // Assuming it is a "." address and return if so if (addr.FromString(hostname)) 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){ WORD dummy; return GetLocalAddress(addr, dummy);}BOOL 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 FALSE; 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 FALSE; addr = address.sin_addr; portNum = ntohs(address.sin_port);#endif return TRUE;}BOOL PIPSocket::GetPeerAddress(Address & addr){ WORD portNum; return GetPeerAddress(addr, portNum);}BOOL 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 FALSE; 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 FALSE; addr = address.sin_addr; portNum = ntohs(address.sin_port);#endif return TRUE;}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();}BOOL PIPSocket::Connect(const PString & host){ Address ipnum;#if P_HAS_IPV6 if (GetHostAddress(host, ipnum)) return Connect(GetDefaultIpAny(), 0, ipnum);#else if (GetHostAddress(host, ipnum)) return Connect(INADDR_ANY, 0, ipnum);#endif return FALSE;}BOOL PIPSocket::Connect(const Address & addr){#if P_HAS_IPV6 return Connect(GetDefaultIpAny(), 0, addr);#else return Connect(INADDR_ANY, 0, addr);#endif}BOOL PIPSocket::Connect(WORD localPort, const Address & addr){#if P_HAS_IPV6 return Connect(GetDefaultIpAny(), localPort, addr);#else return Connect(INADDR_ANY, localPort, addr);#endif}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");#if P_HAS_IPV6 Psockaddr sa(addr, port); // attempt to create a socket with the right family if (!OpenSocket(sa->sa_family)) return FALSE; if (localPort != 0 || iface.IsValid()) { Psockaddr bind_sa(iface, localPort); if (!SetOption(SO_REUSEADDR, 0)) { os_close(); return FALSE; } if (!ConvertOSError(::bind(os_handle, bind_sa, bind_sa.GetSize()))) { os_close(); return FALSE; } } // attempt to connect if (os_connect(sa, sa.GetSize())) return TRUE; #else // attempt to create a socket if (!OpenSocket()) return FALSE; // attempt to connect sockaddr_in sin; if (localPort != 0 || iface.IsValid()) { if (!SetOption(SO_REUSEADDR, 0)) { 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 (os_connect((struct sockaddr *)&sin, sizeof(sin))) return TRUE;#endif os_close(); return FALSE;}BOOL 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}BOOL 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 FALSE;#else if (!OpenSocket()) return FALSE;#endif } #ifndef __BEOS__ // attempt to listen if (!SetOption(SO_REUSEADDR, reuse == CanReuseAddress ? 1 : 0)) { os_close(); return FALSE; }#else // attempt to listen int value = reuse == CanReuseAddress ? 1 : 0; if (!SetOption(SO_REUSEADDR, &value, sizeof(int))) { os_close(); return FALSE; }#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)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -