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

📄 sockets.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:

BOOL PIPSocket::Listen(unsigned queueSize, WORD newPort, Reusability reuse)
{
  return Listen(INADDR_ANY, queueSize, newPort, reuse);
}


BOOL PIPSocket::Listen(const Address & bindAddr,
                       unsigned,
                       WORD newPort,
                       Reusability reuse)
{
  // make sure we have a port
  if (newPort != 0)
    port = newPort;

  // close the port if it is already open
  if (!IsOpen()) {
    // attempt to create a socket
    if (!OpenSocket())
      return FALSE;
  }

  // attempt to listen
  if (SetOption(SO_REUSEADDR, reuse == CanReuseAddress ? 1 : 0)) {
    // attempt to listen
    sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family      = AF_INET;
    sin.sin_addr.s_addr = bindAddr;
    sin.sin_port        = htons(port);       // set the port

#ifdef __NUCLEUS_NET__
    int bind_result;
    if (port == 0)
      bind_result = ::bindzero(os_handle, (struct sockaddr*)&sin, sizeof(sin));
    else
      bind_result = ::bind(os_handle, (struct sockaddr*)&sin, sizeof(sin));
    if (ConvertOSError(bind_result)) {
#else
    if (ConvertOSError(::bind(os_handle, (struct sockaddr*)&sin, sizeof(sin)))) {
#endif
      socklen_t size = sizeof(sin);
      if (ConvertOSError(::getsockname(os_handle, (struct sockaddr*)&sin, &size))) {
        port = ntohs(sin.sin_port);
        return TRUE;
      }
    }
  }

  os_close();
  return FALSE;
}


PIPSocket::Address::Address()
{
  s_addr = inet_addr("127.0.0.1");
}


PIPSocket::Address::Address(const in_addr & addr)
{
  s_addr = addr.s_addr;
}


PIPSocket::Address::Address(const Address & addr)
{
  s_addr = addr.s_addr;
}


PIPSocket::Address::Address(const PString & dotNotation)
{
  operator=(dotNotation);
}


#ifdef __NUCLEUS_NET__
PIPSocket::Address::Address(const struct id_struct & addr)
{
  operator=(addr);
}


PIPSocket::Address & PIPSocket::Address::operator=(const struct id_struct & addr)
{
  s_addr = (((unsigned long)addr.is_ip_addrs[0])<<24) +
           (((unsigned long)addr.is_ip_addrs[1])<<16) +
           (((unsigned long)addr.is_ip_addrs[2])<<8) +
           (((unsigned long)addr.is_ip_addrs[3]));
  return *this;
}
#endif


PIPSocket::Address & PIPSocket::Address::operator=(const in_addr & addr)
{
  s_addr = addr.s_addr;
  return *this;
}


PIPSocket::Address & PIPSocket::Address::operator=(const Address & addr)
{
  s_addr = addr.s_addr;
  return *this;
}


PIPSocket::Address & PIPSocket::Address::operator=(const PString & dotNotation)
{
  if (::strspn(dotNotation, "0123456789.") < ::strlen(dotNotation))
    s_addr = 0;
  else {
    s_addr = inet_addr((const char *)dotNotation);
    if (s_addr == (DWORD)INADDR_NONE)
      s_addr = 0;
  }
  return *this;
}


PString PIPSocket::Address::AsString() const
{
  return inet_ntoa(*this);
}


PIPSocket::Address::operator PString() const
{
  return inet_ntoa(*this);
}


BYTE PIPSocket::Address::operator[](PINDEX idx) const
{
  PASSERTINDEX(idx);
  PAssert(idx <= 3, PInvalidParameter);
  return ((BYTE *)this)[idx];
}


ostream & operator<<(ostream & s, const PIPSocket::Address & a)
{
  return s << inet_ntoa(a);
}


istream & operator>>(istream & s, PIPSocket::Address & a)
{
  char dot1, dot2, dot3;
  unsigned b1, b2, b3, b4;
  s >> b1 >> dot1 >> b2 >> dot2 >> b3 >> dot3 >> b4;
  if (!s && (dot1 != '.' || dot2 != '.' || dot3 != '.'))
    s.clear(ios::failbit);

  a = PIPSocket::Address((BYTE)b1, (BYTE)b2, (BYTE)b3, (BYTE)b4);
  return s;
}


PIPSocket::InterfaceEntry::InterfaceEntry(const PString & _name,
                                          const Address & _addr,
                                          const Address & _mask,
                                          const PString & _macAddr)
  : name(_name.Trim()),
    ipAddr(_addr),
    netMask(_mask),
    macAddr(_macAddr)
{
}


void PIPSocket::InterfaceEntry::PrintOn(ostream & strm) const
{
  strm << ipAddr;
  if (!macAddr)
    strm << " <" << macAddr << '>';
  if (!name)
    strm << " (" << name << ')';
}


#ifdef __NUCLEUS_NET__
BOOL PIPSocket::GetInterfaceTable(InterfaceTable & table)
{
    InterfaceEntry *IE;
    list<IPInterface>::iterator i;
    for(i=Route4Configuration->Getm_IPInterfaceList().begin();
            i!=Route4Configuration->Getm_IPInterfaceList().end();
            i++)
    {
        char ma[6];
        for(int j=0; j<6; j++) ma[j]=(*i).Getm_macaddr(j);
        IE = new InterfaceEntry((*i).Getm_name().c_str(), (*i).Getm_ipaddr(), ma );
        if(!IE) return false;
        table.Append(IE);
    }
    return true;
}
#endif


//////////////////////////////////////////////////////////////////////////////
// PTCPSocket

PTCPSocket::PTCPSocket(WORD newPort)
{
  SetPort(newPort);
}


PTCPSocket::PTCPSocket(const PString & service)
{
  SetPort(service);
}


PTCPSocket::PTCPSocket(const PString & address, WORD newPort)
{
  SetPort(newPort);
  Connect(address);
}


PTCPSocket::PTCPSocket(const PString & address, const PString & service)
{
  SetPort(service);
  Connect(address);
}


PTCPSocket::PTCPSocket(PSocket & socket)
{
  Accept(socket);
}


PTCPSocket::PTCPSocket(PTCPSocket & tcpSocket)
{
  Accept(tcpSocket);
}


PObject * PTCPSocket::Clone() const
{
  return new PTCPSocket(port);
}


BOOL PTCPSocket::OpenSocket()
{
  return ConvertOSError(os_handle = os_socket(AF_INET, SOCK_STREAM, 0));
}


const char * PTCPSocket::GetProtocolName() const
{
  return "tcp";
}


BOOL PTCPSocket::Write(const void * buf, PINDEX len)
{
  flush();
  PINDEX writeCount = 0;

  while (len > 0) {
    if (!os_sendto(((char *)buf)+writeCount, len, 0, NULL, 0))
      return FALSE;
    writeCount += lastWriteCount;
    len -= lastWriteCount;
  }

  lastWriteCount = writeCount;
  return TRUE;
}


BOOL PTCPSocket::Listen(unsigned queueSize, WORD newPort, Reusability reuse)
{
  return Listen(INADDR_ANY, queueSize, newPort, reuse);
}


BOOL PTCPSocket::Listen(const Address & bindAddr,
                        unsigned queueSize,
                        WORD newPort,
                        Reusability reuse)
{
  if (PIPSocket::Listen(bindAddr, queueSize, newPort, reuse) &&
      ConvertOSError(::listen(os_handle, queueSize)))
    return TRUE;

  os_close();
  return FALSE;
}


BOOL PTCPSocket::Accept(PSocket & socket)
{
  PAssert(socket.IsDescendant(PIPSocket::Class()), "Invalid listener socket");

  sockaddr_in address;
  address.sin_family = AF_INET;
  PINDEX size = sizeof(address);
  if (!ConvertOSError(os_handle = os_accept(socket, (struct sockaddr *)&address, &size)))
    return FALSE;

  port = ((PIPSocket &)socket).GetPort();
  return TRUE;
}


BOOL PTCPSocket::WriteOutOfBand(void const * buf, PINDEX len)
{
#ifdef __NUCLEUS_NET__
  PAssertAlways("WriteOutOfBand unavailable on Nucleus Plus");
  //int count = NU_Send(os_handle, (char *)buf, len, 0);
  int count = ::send(os_handle, (const char *)buf, len, 0);
#else
  int count = ::send(os_handle, (const char *)buf, len, MSG_OOB);
#endif
  if (count < 0) {
    lastWriteCount = 0;
    return ConvertOSError(count, LastWriteError);
  }
  else {
    lastWriteCount = count;
    return TRUE;
  }
}


void PTCPSocket::OnOutOfBand(const void *, PINDEX)
{
}


//////////////////////////////////////////////////////////////////////////////
// PIPDatagramSocket

PIPDatagramSocket::PIPDatagramSocket()
{
}


BOOL PIPDatagramSocket::ReadFrom(void * buf, PINDEX len,
                                 Address & addr, WORD & port)
{
  lastReadCount = 0;

  sockaddr_in sockAddr;
  PINDEX addrLen = sizeof(sockAddr);
  if (os_recvfrom(buf, len, 0, (struct sockaddr *)&sockAddr, &addrLen)) {
    addr = sockAddr.sin_addr;
    port = ntohs(sockAddr.sin_port);
  }

  return lastReadCount > 0;
}


BOOL PIPDatagramSocket::WriteTo(const void * buf, PINDEX len,
                                const Address & addr, WORD port)
{
  lastWriteCount = 0;

  sockaddr_in sockAddr;
  sockAddr.sin_family = AF_INET;
  sockAddr.sin_addr = addr;
  sockAddr.sin_port = htons(port);
  return os_sendto(buf, len, 0, (struct sockaddr *)&sockAddr, sizeof(sockAddr))
         && lastWriteCount >= len;
}


//////////////////////////////////////////////////////////////////////////////
// PUDPSocket

PUDPSocket::PUDPSocket(WORD newPort)
{
  sendPort = 0;
  SetPort(newPort);
  OpenSocket();
}


PUDPSocket::PUDPSocket(const PString & service)
{
  sendPort = 0;
  SetPort(service);
  OpenSocket();
}


PUDPSocket::PUDPSocket(const PString & address, WORD newPort)
{
  sendPort = 0;
  SetPort(newPort);
  Connect(address);
}


PUDPSocket::PUDPSocket(const PString & address, const PString & service)
{
  sendPort = 0;
  SetPort(service);
  Connect(address);
}


BOOL PUDPSocket::OpenSocket()
{
  return ConvertOSError(os_handle = os_socket(AF_INET, SOCK_DGRAM, 0));
}


const char * PUDPSocket::GetProtocolName() const
{
  return "udp";
}


BOOL PUDPSocket::Connect(const PString & address)
{
  sendPort = 0;
  return PIPDatagramSocket::Connect(address);
}


BOOL PUDPSocket::Read(void * buf, PINDEX len)
{
  return PIPDatagramSocket::ReadFrom(buf, len, lastReceiveAddress, lastReceivePort);
}


BOOL PUDPSocket::Write(const void * buf, PINDEX len)
{
  if (sendPort == 0)
    return PIPDatagramSocket::Write(buf, len);
  else
    return PIPDatagramSocket::WriteTo(buf, len, sendAddress, sendPort);
}


void PUDPSocket::SetSendAddress(const Address & newAddress, WORD newPort)
{
  sendAddress = newAddress;
  sendPort    = newPort;
}


void PUDPSocket::GetSendAddress(Address & address, WORD & port)
{
  address = sendAddress;
  port    = sendPort;
}


void PUDPSocket::GetLastReceiveAddress(Address & address, WORD & port)
{
  address = lastReceiveAddress;
  port    = lastReceivePort;
}


// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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