Logo Search packages:      
Sourcecode: pwlib version File versions  Download package

BOOL PIPSocket::Listen ( const Address bind,
unsigned  queueSize = 5,
WORD  port = 0,
Reusability  reuse = AddressIsExclusive 
) [virtual, inherited]

Parameters:
bind  Local interface address to bind to.
queueSize  Number of pending accepts that may be queued.
port  Port number to use for the connection.
reuse  Can/Can't listen more than once.

Reimplemented in PTCPSocket.

Definition at line 2063 of file sockets.cxx.

References PChannel::Close(), PChannel::ConvertOSError(), PSocket::GetOption(), PChannel::IsOpen(), PChannel::os_handle, and PSocket::SetOption().

{
  // 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)))
      return FALSE;

    port = sa.GetPort();
    return TRUE;
  }

#else

  // 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;
    }
  }

#endif

  os_close();
  return FALSE;
}


Generated by  Doxygen 1.6.0   Back to index