inlib  1.2.0
Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes
inlib::net::inet_socket Class Reference
Inheritance diagram for inlib::net::inet_socket:
Inheritance graph
[legend]
Collaboration diagram for inlib::net::inet_socket:
Collaboration graph
[legend]

List of all members.

Classes

struct  bind_info

Public Types

typedef bool(* after_bind_func )(const bind_info &, void *)
typedef bool(* accept_func )(void *)

Public Member Functions

virtual void disconnect ()
 inet_socket (std::ostream &a_out, bool a_verbose=false)
virtual ~inet_socket ()
void set_after_bind_func (after_bind_func aFunc, void *aTag)
void set_accept_func (accept_func aFunc, void *aTag)
bool bind (const std::string &a_host, int a_port, unsigned int a_max_trial, unsigned int a_secs, bool a_reuse_addr)
bool accept (int a_socket, bool a_blocking)
bool bind_accept (const std::string &a_host, int a_port, unsigned int a_max_trial, unsigned int a_secs, bool a_reuse_addr, bool a_blocking)
bool connect (const std::string &a_host, int a_port, unsigned int a_max_trial, unsigned int a_secs)

Protected Member Functions

 inet_socket (const inet_socket &a_from)
inet_socketoperator= (const inet_socket &)

Protected Attributes

after_bind_func m_after_bind_func
void * m_after_bind_tag
accept_func m_accept_func
void * m_accept_tag

Detailed Description

Definition at line 88 of file inet_socket.


Member Typedef Documentation

typedef bool(* inlib::net::inet_socket::accept_func)(void *)

Definition at line 144 of file inet_socket.

typedef bool(* inlib::net::inet_socket::after_bind_func)(const bind_info &, void *)

Definition at line 137 of file inet_socket.


Constructor & Destructor Documentation

inlib::net::inet_socket::inet_socket ( std::ostream &  a_out,
bool  a_verbose = false 
) [inline]

Definition at line 92 of file inet_socket.

  :base_socket(a_out,a_verbose)
  ,m_after_bind_func(0)
  ,m_after_bind_tag(0)
  ,m_accept_func(0)
  ,m_accept_tag(0)
  { 
#ifdef WIN32
    WSADATA data;
    if (::WSAStartup(MAKEWORD(2,2),&data)!=NO_ERROR) {
      m_out << "inlib::inet_socket::inet_socket :"
            << " starting sockets failed." 
            << std::endl;
    } else {
      if(a_verbose) {
        m_out << "inlib::inet_socket::inet_socket :"
              << " WSAStartup ok." 
              << std::endl;
      }
    }
#endif
  }
virtual inlib::net::inet_socket::~inet_socket ( ) [inline, virtual]

Definition at line 115 of file inet_socket.

                         {
    close(); //WIN32 : must be done before the below.
#ifdef WIN32
    ::WSACleanup();
#endif
  }
inlib::net::inet_socket::inet_socket ( const inet_socket a_from) [inline, protected]

Definition at line 123 of file inet_socket.

  :base_socket(a_from)
  ,m_after_bind_func(a_from.m_after_bind_func)
  ,m_after_bind_tag(a_from.m_after_bind_tag)
  ,m_accept_func(a_from.m_accept_func)
  ,m_accept_tag(a_from.m_accept_tag)
  {}

Member Function Documentation

bool inlib::net::inet_socket::accept ( int  a_socket,
bool  a_blocking 
) [inline]

Definition at line 303 of file inet_socket.

                                           {
    if(m_socket!=(-1)) return true; //Done.

    std::string this_host;
    if(!host_name(m_out,this_host)) {
      // in this method this_host is used for m_out only
      // then we  ontinue anyway.
      this_host = "not_found";
      //return false;
    }

    if(a_blocking) {
      sockaddr_in address;
      ::memset((char*)&address,0,sizeof(address)); 
#ifdef WIN32
      int
#else
      socklen_t
#endif
      address_length = sizeof(address);
      m_socket = ::accept(a_socket, 
                         (struct sockaddr*)(&address), 
                         &address_length);
      if(m_socket<0) { 
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " accept() : " << serror()
              << std::endl;
        m_socket = -1;
        return false;
      }
      if(m_verbose) {
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " accept ok."
              << " Socket is " << m_socket << "."
              << std::endl;
      }
    } else {
#ifdef WIN32
     {unsigned long val = 1;
      if(::ioctlsocket(a_socket,FIONBIO,&val)!=0) {
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " ioctlsocket FIONBIO failed."
              << std::endl;
        return false;
      }}
#else
      int old_flags = ::fcntl(a_socket,F_GETFL);
      if(old_flags<0) {
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " fcntl F_GETFL failed."
              << std::endl;
        return false;
      }
      if(::fcntl(a_socket,F_SETFL,old_flags+O_NONBLOCK)<0) {
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " fcntl F_SETFL failed."
              << std::endl;
        return false;
      }
#endif
  
      bool status = false;
  
      while(true) {
        sockaddr_in address;
        ::memset((char*)&address,0,sizeof(address)); 
#ifdef WIN32
        int
#else
        socklen_t
#endif
        address_length = sizeof(address);
        int retval = ::accept(a_socket, 
                              (struct sockaddr*)(&address), 
                              &address_length);
        if(retval<0) {
#ifdef WIN32
          if(WSAGetLastError()==WSAEWOULDBLOCK) {
#else
          if(errno==EWOULDBLOCK) {
#endif
            if(m_accept_func)  {
              if(!m_accept_func(m_accept_tag)) {
                status = true;
                break;
              }
            }
            continue;
          } else {
            m_out << "inlib::inet_socket:::accept :"
                  << " on host : " << this_host
                  << " accept() : " << serror()
                  << std::endl;
            status = false;
            break;  
          }
        }
  
        m_socket = retval;
        status = true;
        break;
      }
  
#ifdef WIN32
     {unsigned long val = 0;
      if(::ioctlsocket(a_socket, FIONBIO, &val)!=0) {
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " ioctlsocket FIONBIO failed."
              << std::endl;
        if(m_socket!=(-1)) {
          ::close(m_socket);
          m_socket = -1;
        }
        return false;
      }}
#else
      if(::fcntl(a_socket,F_SETFL,old_flags)<0) {
        m_out << "inlib::inet_socket:::accept :"
              << " on host : " << this_host
              << " fcntl F_SETFL (2) failed."
              << std::endl;
        if(m_socket!=(-1)) {
          ::close(m_socket);
          m_socket = -1;
        }
        return false;
      }
#endif

      if(m_socket!=(-1)) {
#ifdef WIN32
       {unsigned long val = 0;
        if(::ioctlsocket(m_socket,FIONBIO,&val)!=0) {
          m_out << "inlib::inet_socket:::accept :"
                << " on host : " << this_host
                << " ioctlsocket FIONBIO failed."
                << std::endl;
          ::close(m_socket);
          m_socket = -1;
          return false;
        }}
#else
        if(::fcntl(m_socket,F_SETFL,old_flags)<0) {
          m_out << "inlib::inet_socket:::accept :"
                << " on host : " << this_host
                << " fcntl F_SETFL (2) failed."
                << std::endl;
          ::close(m_socket);
          m_socket = -1;
          return false;
        }
#endif
      }

      if(!status) return false;

      if(m_verbose) {
        if(m_socket==(-1)) {
          m_out << "inlib::inet_socket:::accept :"
                << " on host : " << this_host
                << " accept exit without a socket."
                << std::endl;
        } else {
          m_out << "inlib::inet_socket:::accept :"
                << " on host : " << this_host
                << " accept ok."
                << " Socket is " << m_socket << "."
                << std::endl;
        }
      }
    }
  
    return true;
  }
bool inlib::net::inet_socket::bind ( const std::string &  a_host,
int  a_port,
unsigned int  a_max_trial,
unsigned int  a_secs,
bool  a_reuse_addr 
) [inline]

Definition at line 151 of file inet_socket.

                                                                           {   
    if(m_socket!=(-1)) return true; //Done.

    if(m_verbose) {
      m_out << "inlib::inet_socket:::bind :"
            << " host : \"" << a_host << "\"."
            << std::endl;
    }

    in_addr_t addr = 0; //int32
    if(!inet_addr(m_out,a_host,addr)) return false;

    //if(m_verbose) {
    //  m_out << "inlib::inet_socket:::bind :"
    //        << " addr : " << ::inet_ntoa(*(struct in_addr*)&addr) << "."
    //        << std::endl;
    //}

    int fd_socket_waiting;

    unsigned int num_trial = 0;
    while(true) {

      // make socket
      fd_socket_waiting = ::socket(AF_INET,SOCK_STREAM,0);
      if(fd_socket_waiting<0) { 
        m_out << "inlib::inet_socket:::bind :"
              << " on host : " << a_host
              << " socket() : " << serror()
              << std::endl;
        return false;
      }
  
      // Force reuse of the server socket (i.e. do not wait for the time
      // out to pass).
      if(a_reuse_addr) {
        if(!set_reuse_addr(m_out,fd_socket_waiting)) return false;
      }
  
      // binding
      sockaddr_in address;
      ::memset((char*)&address,0,sizeof(address)); 
      address.sin_family = AF_INET;
      address.sin_port = htons(a_port);
      address.sin_addr.s_addr = addr;
  
      if(::bind(fd_socket_waiting,
                (struct sockaddr*)(&address),sizeof(address))==0) {
        if(m_verbose) {
          m_out << "inlib::inet_socket:::bind :"
                << " on host : " << a_host
                << " socket is bound on port " << a_port << "." 
                << std::endl;
        }
        break;
      }
  
#ifdef WIN32
#else
      std::string serror(strerror(errno));
#endif

      ::close(fd_socket_waiting);
  
      if(num_trial>=a_max_trial) { 
        m_out << "inlib::inet_socket:::bind :"
              << " on host : " << a_host
              << " with port " << a_port
              << ". Max trials done. Cannot use port " << a_port << "." 
              << std::endl;
        return false;
      }
      num_trial++;
  
      //FIXME : should filter the errno. Some may be fatal.
      //if(m_verbose) {
        m_out << "inlib::inet_socket:::bind :"
              << " on host : " << a_host
              << " with port " << a_port
#ifdef WIN32
              << " bind()"
#else
              << " bind() : " << serror
#endif
              << " : retry..." 
              << std::endl;
      //}

      sleep_secs(a_secs);                
    }

    sockaddr_in address;
    ::memset((char*)&address,0,sizeof(address)); 
#ifdef WIN32
    int
#else
    socklen_t 
#endif
    address_length = sizeof(address);
    if(::getsockname(fd_socket_waiting,
                     (struct sockaddr*)&address,&address_length)!=0) { 
      m_out << "inlib::inet_socket:::bind :"
            << " on host : " << a_host
            << " getsockname() : " << serror()
            << std::endl;
      return false;
    }

    int true_port = a_port; 
    if(a_port==0) { //get the used port.
      true_port = ntohs(address.sin_port);
      if(m_verbose) {
        m_out << "inlib::inet_socket:::bind :"
              << " on host : " << a_host
              << " getsockname() : port " << true_port << "."
              << std::endl;
      }
    }
  
    if(m_after_bind_func)  {
      //getsockname again !
      bind_info info;
      info.m_true_port = true_port;
      info.m_sin_addr = address.sin_addr.s_addr;
      info.m_sin_port = address.sin_port;
      if(!m_after_bind_func(info,m_after_bind_tag)) return false;
    }
    
    // listen (wait connection)
    if(::listen(fd_socket_waiting,1)<0) { 
      m_out << "inlib::inet_socket:::bind :"
            << " on host : " << a_host
            << " listen() : " << serror()
            << std::endl;
      ::close(fd_socket_waiting);
      return false;
    }

    m_socket = fd_socket_waiting;

    if(m_verbose) {
      m_out << "inlib::inet_socket:::bind :"
            << " on host : " << a_host
            << " bind ok for port " << true_port << "."
            << " Socket is " << m_socket << "."
            << std::endl;
    }
  
    return true;
  }
bool inlib::net::inet_socket::bind_accept ( const std::string &  a_host,
int  a_port,
unsigned int  a_max_trial,
unsigned int  a_secs,
bool  a_reuse_addr,
bool  a_blocking 
) [inline]

Definition at line 484 of file inet_socket.

                                                                                                                                     {
    if(!bind(a_host,a_port,a_max_trial,a_secs,a_reuse_addr)) return false;
    int sock = m_socket;
    m_socket = -1;
    bool status = accept(sock,a_blocking);
    ::close(sock);
    return status;
  }
bool inlib::net::inet_socket::connect ( const std::string &  a_host,
int  a_port,
unsigned int  a_max_trial,
unsigned int  a_secs 
) [inline]

Definition at line 493 of file inet_socket.

                                                                                               {
    if(m_socket!=(-1)) return true; //Done.
  
    std::string this_host;
    if(!host_name(m_out,this_host)) {
      // in this method this_host is used for m_out only
      // then we  ontinue anyway.
      this_host = "not_found";
      //return false;
    }

    //if(m_verbose) {
    //  m_out << "inlib::inet_socket:::connect :"
    //        << " this host : \"" << this_host << "\"."
    //        << std::endl;
    //}

    in_addr_t addr = 0; //int32
    if(!inet_addr(m_out,a_host,addr)) return false;
  
    unsigned int num_trial = 0;
    while(true) {

      // make socket :
      m_socket = ::socket(AF_INET, SOCK_STREAM,0);
      if(m_socket<0) { 
        m_out << "inlib::inet_socket:::connect :"
              << " on host : " << this_host
              << " socket() : " << serror()
              << std::endl;
        m_socket = -1;
        return false;
      }

      sockaddr_in address;
      ::memset((char*)&address,0,sizeof(address)); 
      address.sin_family = AF_INET;
      address.sin_port = htons(a_port);
      address.sin_addr.s_addr = addr;

      if(::connect(m_socket,
                   (struct sockaddr*)(&address),sizeof(address))==0) {
        if(m_verbose) {
          m_out << "inlib::inet_socket:::connect :"
                << " on host : " << this_host
                << " connect to " << a_host << " on port " << a_port << " ok."
                << " Socket is " << m_socket << "."
                << std::endl;
        }
        return true;
      }

#ifdef WIN32
      if(WSAGetLastError()==WSAECONNREFUSED) {
#else
      if(errno==ECONNREFUSED) {
#endif
        if(m_verbose) {
          m_out << "inlib::inet_socket:::connect :"
                << " on host : " << this_host
                << " connect to " << a_host 
                << " with port " << a_port
                << " connect() : " << serror()
                << " Retry..."
                << std::endl;
        }
  
        ::close(m_socket);
        m_socket = -1;
  
        if(num_trial>=a_max_trial) { 
          m_out << "inlib::inet_socket:::connect :"
                << " on host : " << this_host
                << " connect to " << a_host 
                << " with port " << a_port
                << ". Max trials done. Can't connect."
                << std::endl;
          return false;
        }
        num_trial++;
  
        sleep_secs(a_secs);                
      } else {
        m_out << "inlib::inet_socket:::connect :"
              << " on host : " << this_host
              << " connect to " << a_host 
              << " with port " << a_port
              << " connect() : " << serror()
              << std::endl;
        ::close(m_socket);
        m_socket = -1;
        return false;
      }
    }

    return false;
  }
virtual void inlib::net::inet_socket::disconnect ( ) [inline, virtual]

Implements inlib::net::base_socket.

Definition at line 90 of file inet_socket.

{close();}
inet_socket& inlib::net::inet_socket::operator= ( const inet_socket ) [inline, protected]

Definition at line 130 of file inet_socket.

{ return *this;}
void inlib::net::inet_socket::set_accept_func ( accept_func  aFunc,
void *  aTag 
) [inline]

Definition at line 146 of file inet_socket.

                                                    {
    m_accept_func = aFunc;
    m_accept_tag = aTag;
  }
void inlib::net::inet_socket::set_after_bind_func ( after_bind_func  aFunc,
void *  aTag 
) [inline]

Definition at line 139 of file inet_socket.

                                                            {
    m_after_bind_func = aFunc;
    m_after_bind_tag = aTag;
  }

Member Data Documentation

Definition at line 594 of file inet_socket.

Definition at line 595 of file inet_socket.

Definition at line 592 of file inet_socket.

Definition at line 593 of file inet_socket.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines