Logo
~Sockets~
~Examples~
~Contact~


ListenSocket< X > Class Template Reference
[Basic sockets]

Binds incoming port number to new Socket class X. More...

#include <ListenSocket.h>

Inheritance diagram for ListenSocket< X >:
Collaboration diagram for ListenSocket< X >:

List of all members.


Public Member Functions

 ListenSocket (ISocketHandler &h, bool use_creator=true)
 Constructor.
 ~ListenSocket ()
int Close ()
 Close file descriptor.
int Bind (port_t port, int depth=20)
 Bind and listen to any interface.
int Bind (SocketAddress &ad, int depth)
int Bind (port_t port, const std::string &protocol, int depth=20)
 Bind and listen to any interface, with optional protocol.
int Bind (const std::string &intf, port_t port, int depth=20)
 Bind and listen to specific interface.
int Bind (const std::string &intf, port_t port, const std::string &protocol, int depth=20)
 Bind and listen to specific interface.
int Bind (ipaddr_t a, port_t port, int depth=20)
 Bind and listen to ipv4 interface.
int Bind (ipaddr_t a, port_t port, const std::string &protocol, int depth)
 Bind and listen to ipv4 interface.
int Bind (SocketAddress &ad, const std::string &protocol, int depth)
 Bind and listen to network interface.
port_t GetPort ()
 Return assigned port number.
int GetDepth ()
 Return listen queue depth.
void OnRead ()
 OnRead on a ListenSocket receives an incoming connection.
virtual SOCKET Accept (SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr)
 Please don't use this method.
bool HasCreator ()
void OnOptions (int, int, int, SOCKET)
 Called when a client socket is created, to set socket options.

Protected Member Functions

 ListenSocket (const ListenSocket &s)

Private Member Functions

ListenSocketoperator= (const ListenSocket &)

Private Attributes

int m_depth
X * m_creator
bool m_bHasCreate

Detailed Description

template<class X>
class ListenSocket< X >

Binds incoming port number to new Socket class X.

Definition at line 58 of file ListenSocket.h.


Constructor & Destructor Documentation

template<class X>
ListenSocket< X >::ListenSocket ( ISocketHandler h,
bool  use_creator = true 
) [inline]

Constructor.

Parameters:
h ISocketHandler reference
use_creator Optional use of creator (default true)

Definition at line 64 of file ListenSocket.h.

00064                                                                 : Socket(h), m_depth(0), m_creator(NULL)
00065         ,m_bHasCreate(false)
00066         {
00067                 if (use_creator)
00068                 {
00069                         m_creator = new X(h);
00070                         Socket *tmp = m_creator -> Create();
00071                         if (tmp && dynamic_cast<X *>(tmp))
00072                         {
00073                                 m_bHasCreate = true;
00074                         }
00075                         if (tmp)
00076                         {
00077                                 delete tmp;
00078                         }
00079                 }
00080         }

template<class X>
ListenSocket< X >::~ListenSocket (  )  [inline]

Definition at line 81 of file ListenSocket.h.

00081                         {
00082                 if (m_creator)
00083                 {
00084                         delete m_creator;
00085                 }
00086         }

template<class X>
ListenSocket< X >::ListenSocket ( const ListenSocket< X > &  s  )  [inline, protected]

Definition at line 423 of file ListenSocket.h.

00423 : Socket(s) {}


Member Function Documentation

template<class X>
int ListenSocket< X >::Close (  )  [inline, virtual]

Close file descriptor.

Reimplemented from Socket.

Definition at line 89 of file ListenSocket.h.

References closesocket, and INVALID_SOCKET.

00089                     {
00090                 if (GetSocket() != INVALID_SOCKET)
00091                 {
00092                         closesocket(GetSocket());
00093                 }
00094                 return 0;
00095         }

template<class X>
int ListenSocket< X >::Bind ( port_t  port,
int  depth = 20 
) [inline]

Bind and listen to any interface.

Parameters:
port Port (0 is random)
depth Listen queue depth

Definition at line 100 of file ListenSocket.h.

Referenced by ResolvServer::Run().

00100                                              {
00101 #ifdef ENABLE_IPV6
00102 #ifdef IPPROTO_IPV6
00103                 if (IsIpv6())
00104                 {
00105                         Ipv6Address ad(port);
00106                         return Bind(ad, depth);
00107                 }
00108                 else
00109 #endif
00110 #endif
00111                 {
00112                         Ipv4Address ad(port);
00113                         return Bind(ad, depth);
00114                 }
00115         }

template<class X>
int ListenSocket< X >::Bind ( SocketAddress ad,
int  depth 
) [inline]

Definition at line 117 of file ListenSocket.h.

00117                                               {
00118 #ifdef USE_SCTP
00119                 if (dynamic_cast<SctpSocket *>(m_creator))
00120                 {
00121                         return Bind(ad, "sctp", depth);
00122                 }
00123 #endif
00124                 return Bind(ad, "tcp", depth);
00125         }

template<class X>
int ListenSocket< X >::Bind ( port_t  port,
const std::string &  protocol,
int  depth = 20 
) [inline]

Bind and listen to any interface, with optional protocol.

Parameters:
port Port (0 is random)
protocol Network protocol
depth Listen queue depth

Definition at line 131 of file ListenSocket.h.

00131                                                                        {
00132 #ifdef ENABLE_IPV6
00133 #ifdef IPPROTO_IPV6
00134                 if (IsIpv6())
00135                 {
00136                         Ipv6Address ad(port);
00137                         return Bind(ad, protocol, depth);
00138                 }
00139                 else
00140 #endif
00141 #endif
00142                 {
00143                         Ipv4Address ad(port);
00144                         return Bind(ad, protocol, depth);
00145                 }
00146         }

template<class X>
int ListenSocket< X >::Bind ( const std::string &  intf,
port_t  port,
int  depth = 20 
) [inline]

Bind and listen to specific interface.

Parameters:
intf Interface hostname
port Port (0 is random)
depth Listen queue depth

Definition at line 152 of file ListenSocket.h.

References Ipv4Address::IsValid(), and LOG_LEVEL_FATAL.

00152                                                                    {
00153 #ifdef ENABLE_IPV6
00154 #ifdef IPPROTO_IPV6
00155                 if (IsIpv6())
00156                 {
00157                         Ipv6Address ad(intf, port);
00158                         if (ad.IsValid())
00159                         {
00160                                 return Bind(ad, depth);
00161                         }
00162                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00163                         return -1;
00164                 }
00165                 else
00166 #endif
00167 #endif
00168                 {
00169                         Ipv4Address ad(intf, port);
00170                         if (ad.IsValid())
00171                         {
00172                                 return Bind(ad, depth);
00173                         }
00174                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00175                         return -1;
00176                 }
00177         }

template<class X>
int ListenSocket< X >::Bind ( const std::string &  intf,
port_t  port,
const std::string &  protocol,
int  depth = 20 
) [inline]

Bind and listen to specific interface.

Parameters:
intf Interface hostname
port Port (0 is random)
protocol Network protocol
depth Listen queue depth

Definition at line 184 of file ListenSocket.h.

References Ipv4Address::IsValid(), and LOG_LEVEL_FATAL.

00184                                                                                              {
00185 #ifdef ENABLE_IPV6
00186 #ifdef IPPROTO_IPV6
00187                 if (IsIpv6())
00188                 {
00189                         Ipv6Address ad(intf, port);
00190                         if (ad.IsValid())
00191                         {
00192                                 return Bind(ad, protocol, depth);
00193                         }
00194                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00195                         return -1;
00196                 }
00197                 else
00198 #endif
00199 #endif
00200                 {
00201                         Ipv4Address ad(intf, port);
00202                         if (ad.IsValid())
00203                         {
00204                                 return Bind(ad, protocol, depth);
00205                         }
00206                         Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
00207                         return -1;
00208                 }
00209         }

template<class X>
int ListenSocket< X >::Bind ( ipaddr_t  a,
port_t  port,
int  depth = 20 
) [inline]

Bind and listen to ipv4 interface.

Parameters:
a Ipv4 interface address
port Port (0 is random)
depth Listen queue depth

Definition at line 215 of file ListenSocket.h.

00215                                                         {
00216                 Ipv4Address ad(a, port);
00217 #ifdef USE_SCTP
00218                 if (dynamic_cast<SctpSocket *>(m_creator))
00219                 {
00220                         return Bind(ad, "sctp", depth);
00221                 }
00222 #endif
00223                 return Bind(ad, "tcp", depth);
00224         }

template<class X>
int ListenSocket< X >::Bind ( ipaddr_t  a,
port_t  port,
const std::string &  protocol,
int  depth 
) [inline]

Bind and listen to ipv4 interface.

Parameters:
a Ipv4 interface address
port Port (0 is random)
protocol Network protocol
depth Listen queue depth

Definition at line 230 of file ListenSocket.h.

00230                                                                              {
00231                 Ipv4Address ad(a, port);
00232                 return Bind(ad, protocol, depth);
00233         }

template<class X>
int ListenSocket< X >::Bind ( SocketAddress ad,
const std::string &  protocol,
int  depth 
) [inline]

Bind and listen to network interface.

Parameters:
ad Interface address
protocol Network protocol
depth Listen queue depth

Definition at line 267 of file ListenSocket.h.

References closesocket, Errno, SocketAddress::GetFamily(), SocketAddress::GetPort(), INVALID_SOCKET, Utility::l2string(), LOG_LEVEL_FATAL, and StrError.

00267                                                                         {
00268                 SOCKET s;
00269                 if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET)
00270                 {
00271                         return -1;
00272                 }
00273                 // socket must be nonblocking for async connect
00274                 if (!SetNonblocking(true, s))
00275                 {
00276                         closesocket(s);
00277                         return -1;
00278                 }
00279                 if (bind(s, ad, ad) == -1)
00280                 {
00281                         Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00282                         closesocket(s);
00283 #ifdef ENABLE_EXCEPTIONS
00284                         throw Exception("bind() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno));
00285 #endif
00286                         return -1;
00287                 }
00288                 if (listen(s, depth) == -1)
00289                 {
00290                         Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00291                         closesocket(s);
00292 #ifdef ENABLE_EXCEPTIONS
00293                         throw Exception("listen() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno));
00294 #endif
00295                         return -1;
00296                 }
00297                 m_depth = depth;
00298                 Attach(s);
00299                 return 0;
00300         }

template<class X>
port_t ListenSocket< X >::GetPort (  )  [inline, virtual]

Return assigned port number.

Reimplemented from Socket.

Definition at line 303 of file ListenSocket.h.

00304         {
00305                 return GetSockPort();
00306         }

template<class X>
int ListenSocket< X >::GetDepth (  )  [inline]

Return listen queue depth.

Definition at line 309 of file ListenSocket.h.

00310         {
00311                 return m_depth;
00312         }

template<class X>
void ListenSocket< X >::OnRead (  )  [inline, virtual]

OnRead on a ListenSocket receives an incoming connection.

Reimplemented from Socket.

Definition at line 315 of file ListenSocket.h.

References closesocket, Errno, INVALID_SOCKET, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, and StrError.

00316         {
00317                 struct sockaddr sa;
00318                 int max = 10; // process max 10 incoming connection in one call
00319                 while (max--)
00320                 {
00321                         socklen_t sa_len = sizeof(struct sockaddr);
00322                         SOCKET a_s = accept(GetSocket(), &sa, &sa_len);
00323 
00324                         if (a_s == INVALID_SOCKET)
00325                         {
00326                                 // EAGAIN or EWOULDBLOCK
00327 #ifdef _WIN32
00328                                 if (Errno != WSAEWOULDBLOCK)
00329 #else
00330                                 if (Errno != EWOULDBLOCK)
00331 #endif
00332                                 {
00333                                         Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR);
00334                                 }
00335                                 return;
00336                         }
00337                         if (!Handler().OkToAccept(this))
00338                         {
00339                                 Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING);
00340                                 closesocket(a_s);
00341                                 return;
00342                         }
00343                         if (Handler().GetCount() >= FD_SETSIZE)
00344                         {
00345                                 Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler fd_set limit reached", LOG_LEVEL_FATAL);
00346                                 closesocket(a_s);
00347                                 return;
00348                         }
00349                         Socket *tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler());
00350 #ifdef ENABLE_IPV6
00351                         tmp -> SetIpv6( IsIpv6() );
00352 #endif
00353                         tmp -> SetParent(this);
00354                         tmp -> Attach(a_s);
00355                         tmp -> SetNonblocking(true);
00356                         {
00357 #ifdef ENABLE_IPV6
00358 #ifdef IPPROTO_IPV6
00359                                 if (sa_len == sizeof(struct sockaddr_in6))
00360                                 {
00361                                         struct sockaddr_in6 *p = (struct sockaddr_in6 *)&sa;
00362                                         if (p -> sin6_family == AF_INET6)
00363                                         {
00364                                                 Ipv6Address ad(p -> sin6_addr,ntohs(p -> sin6_port));
00365                                                 ad.SetFlowinfo(p -> sin6_flowinfo);
00366 #ifndef _WIN32
00367                                                 ad.SetScopeId(p -> sin6_scope_id);
00368 #endif
00369                                                 tmp -> SetRemoteAddress(ad);
00370                                         }
00371                                 }
00372 #endif
00373 #endif
00374                                 if (sa_len == sizeof(struct sockaddr_in))
00375                                 {
00376                                         struct sockaddr_in *p = (struct sockaddr_in *)&sa;
00377                                         if (p -> sin_family == AF_INET)
00378                                         {
00379                                                 Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port));
00380                                                 tmp -> SetRemoteAddress(ad);
00381                                         }
00382                                 }
00383                         }
00384                         tmp -> SetConnected(true);
00385                         tmp -> Init();
00386                         tmp -> SetDeleteByHandler(true);
00387                         Handler().Add(tmp);
00388 #ifdef HAVE_OPENSSL
00389                         if (tmp -> IsSSL()) // SSL Enabled socket
00390                         {
00391                                 // %! OnSSLAccept calls SSLNegotiate that can finish in this one call.
00392                                 // %! If that happens and negotiation fails, the 'tmp' instance is
00393                                 // %! still added to the list of active sockets in the sockethandler.
00394                                 // %! See bugfix for this in SocketHandler::Select - don't Set rwx
00395                                 // %! flags if CloseAndDelete() flag is true.
00396                                 // %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids
00397                                 // %! the Add problem altogether, so ignore the above.
00398                                 // %! (OnSSLAccept does no longer call SSLNegotiate().)
00399                                 tmp -> OnSSLAccept();
00400                         }
00401                         else
00402 #endif
00403                         {
00404                                 tmp -> OnAccept();
00405                         }
00406                 } // while (true)
00407         }

template<class X>
virtual SOCKET ListenSocket< X >::Accept ( SOCKET  socket,
struct sockaddr *  saptr,
socklen_t *  lenptr 
) [inline, virtual]

Please don't use this method.

"accept()" is handled automatically in the OnRead() method.

Definition at line 411 of file ListenSocket.h.

00412         {
00413                 return accept(socket, saptr, lenptr);
00414         }

template<class X>
bool ListenSocket< X >::HasCreator (  )  [inline]

Definition at line 416 of file ListenSocket.h.

00416 { return m_bHasCreate; }

template<class X>
void ListenSocket< X >::OnOptions ( int  family,
int  type,
int  protocol,
SOCKET  s 
) [inline, virtual]

Called when a client socket is created, to set socket options.

Parameters:
family AF_INET, AF_INET6, etc
type SOCK_STREAM, SOCK_DGRAM, etc
protocol Protocol number (tcp, udp, sctp, etc)
s Socket file descriptor

Implements Socket.

Definition at line 418 of file ListenSocket.h.

00418                                            {
00419                 SetSoReuseaddr(true);
00420         }

template<class X>
ListenSocket& ListenSocket< X >::operator= ( const ListenSocket< X > &   )  [inline, private]

Definition at line 425 of file ListenSocket.h.

00425 { return *this; }


Member Data Documentation

template<class X>
int ListenSocket< X >::m_depth [private]

Definition at line 426 of file ListenSocket.h.

template<class X>
X* ListenSocket< X >::m_creator [private]

Definition at line 427 of file ListenSocket.h.

template<class X>
bool ListenSocket< X >::m_bHasCreate [private]

Definition at line 428 of file ListenSocket.h.


The documentation for this class was generated from the following file:
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4