📄 sockets.cxx
字号:
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 + -