libsocket 1.5
Network::Socket Class Reference

This class represent an abstract socket connection (udp | tcp server | tcp client) More...

#include <socket.hh>

Inheritance diagram for Network::Socket:
Network::LocalSocket Network::NetSocket Network::TcpSocket Network::UdpSocket

List of all members.

Public Member Functions

 Socket (SOCKET_KIND kind, SOCKET_VERSION version=V4)
 Socket (SOCKET_KIND kind, PROTO_KIND pkind, SOCKET_VERSION version=V4)
virtual ~Socket ()
void write (const std::string &str)
 function used by << operator (write a string on current socket)
bool connected () const
 return true when socket is connected
int get_socket ()
 get socket (fd) warning: be very carefull with this method
void add_delim (const std::string &delim)
 set the delimitor for the text mode
void del_delim (const std::string &delim)
 delete this delimitor for the socket
void allow_empty_lines ()
 , if set, empty lines will be returned in text procols (if not, they are skipped)
void init_tls (GnuTLSKind kind, unsigned size=1024, const std::string &certfile="", const std::string &keyfile="", const std::string &trustfile="", const std::string &crlfile="")
 
Exceptions:
TLSSupportErrorwhen TLS is not enabled

void enable_tls ()
 Enable TLS on socket.
virtual std::string read ()=0
 function used by >> operator (read a string on current socket)
virtual std::string read (int timeout)=0
 read a string with a timeout
virtual std::string readn (unsigned int size)=0
 read a string from socket
virtual std::string readn (int timeout, unsigned int size)=0
 read a string with a timeout

Protected Member Functions

void _close (int socket) const
 Close a connnection

Exceptions:
CloseExceptionwhen close libc function return a negative value.

void _listen (int socket) const
 Listen on port

Exceptions:
ListenExceptionwhen listen libc function return a negative value.

virtual std::string _read_line (int socket)=0
 Get a line from socket (when used with textual protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

virtual std::string _read_line_bin (int socket, unsigned int size)=0
 Get a line from socket (when used with binary protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

void _write_str (int socket, const std::string &str) const
 Write a string to a socket (when used with textual protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

void _write_str_bin (int socket, const std::string &str) const
 Write a string to a socket (when used with binary protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

void _set_timeout (bool enable, int socket, int timeout)
 set a timeout on a socket
std::pair< int, int > _find_delim (const std::string &str, int start) const
bool _update_buffer (std::pair< int, int > &delim, int &i, std::string &str)
 look delimiter and remove delimiter at begining of buffer if needed
bool _check_answer (int res, std::string &str)
 return the content of the buffer is there is

Protected Attributes

SOCKET_KIND _kind
SOCKET_VERSION _version
unsigned _state_timeout
int _socket
int _recv_flags
struct sockaddr_in _addr
PROTO_KIND _proto_kind
std::list< std::string > _delim
bool _empty_lines
std::string _buffer
bool _tls

Detailed Description

This class represent an abstract socket connection (udp | tcp server | tcp client)

Author:
Julien Lemoine <speedblue at="" happycoders="" dot="" org>="">

Definition at line 100 of file socket.hh.


Constructor & Destructor Documentation

Network::Socket::Socket ( SOCKET_KIND  kind,
SOCKET_VERSION  version = V4 
)

Definition at line 31 of file socket.cc.

References _delim, HERE, and Network::V6.

                                                         :
    _kind(kind), _version(version), _state_timeout(0),
    _socket(0), _recv_flags(kind), _proto_kind(text), _empty_lines(false),
    _buffer(""), _tls(false)
  {
    _delim.push_back("\0");
#ifdef LIBSOCKET_WIN
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0)
      throw WSAStartupError("WSAStartup failed", HERE);
#endif
#ifndef IPV6_ENABLED
    if (version == V6)
      throw Ipv6SupportError("lib was not compiled with ipv6 support", HERE);
#endif
  }
Network::Socket::Socket ( SOCKET_KIND  kind,
PROTO_KIND  pkind,
SOCKET_VERSION  version = V4 
)

Definition at line 48 of file socket.cc.

References _delim, HERE, and Network::V6.

                                                                           :
    _kind(kind), _version(version), _state_timeout(0),
    _socket(0), _recv_flags(kind), _proto_kind(pkind), _empty_lines(false),
    _buffer(""), _tls(false)
  {
    _delim.push_back("\0");
#ifdef LIBSOCKET_WIN
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0)
      throw WSAStartupError("WSAStartup failed", HERE);
#endif
#ifndef IPV6_ENABLED
    if (version == V6)
      throw Ipv6SupportError("lib was not compiled with ipv6 support", HERE);
#endif
  }
Network::Socket::~Socket ( ) [virtual]

Definition at line 65 of file socket.cc.

  {
  }

Member Function Documentation

bool Network::Socket::_check_answer ( int  res,
std::string &  str 
) [inline, protected]

return the content of the buffer is there is

Definition at line 28 of file socket.hxx.

References _buffer, _state_timeout, and HERE.

Referenced by Network::NetSocket::_read_line().

  {
    if (res <= 0)
      {
        if (!_buffer.size()) // No more data...
          throw ConnectionClosed("Connection Closed", HERE);
        else
          {
            str += _buffer;
            _buffer = "";
            _state_timeout = 0;
            return true;
          }
      }
    return false;
  }
void Network::Socket::_close ( int  socket) const [protected]

Close a connnection

Exceptions:
CloseExceptionwhen close libc function return a negative value.

Definition at line 167 of file socket.cc.

References _tls, and HERE.

Referenced by Network::UdpSocket::close(), Network::TcpSocket::close(), and Network::LocalSocket::close().

  {
#ifndef LIBSOCKET_WIN
    if (socket < 0 || close(socket) < 0)
      throw CloseError("Close Error", HERE);
    socket = 0;
#else
    if (socket < 0 || closesocket(socket) < 0)
      throw CloseError("Close Error", HERE);
    socket = 0;
#endif
#ifdef TLS
    if (_tls)
      {
        std::cout << "Deletion..." << std::endl;
        gnutls_deinit(_session);
        if (_tls_main)
          {
            gnutls_certificate_free_credentials(_x509_cred);
            gnutls_global_deinit();
          }
      }
#endif
  }
std::pair< int, int > Network::Socket::_find_delim ( const std::string &  str,
int  start 
) const [protected]

Definition at line 339 of file socket.cc.

References _delim.

Referenced by _update_buffer().

  {
    int                                         i = -1;
    int                                         pos = -1, size = 0;
    std::list<std::string>::const_iterator      it;

    // Looking for the first delimiter.
    if (_delim.size() > 0)
      {
        it = _delim.begin();
        while (it != _delim.end())
          {
            if (*it == "")
              i = str.find('\0', start);
            else
              i = str.find(*it, start);
            if ((i >= 0) && ((unsigned int)i < str.size()) &&
                (pos < 0 || i < pos))
              {
                pos = i;
                size = it->size() ? it->size() : 1;
              }
            it++;
          }
      }
    return std::pair<int, int>(pos, size);
  }
void Network::Socket::_listen ( int  socket) const [protected]

Listen on port

Exceptions:
ListenExceptionwhen listen libc function return a negative value.

Definition at line 192 of file socket.cc.

References HERE.

Referenced by Network::TcpSocket::connect().

  {
    if (socket < 0 || listen(socket, 5) < 0)
      throw ListenError("Listen Error", HERE);
  }
virtual std::string Network::Socket::_read_line ( int  socket) [protected, pure virtual]

Get a line from socket (when used with textual protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

Implemented in Network::LocalSocket, and Network::NetSocket.

virtual std::string Network::Socket::_read_line_bin ( int  socket,
unsigned int  size 
) [protected, pure virtual]

Get a line from socket (when used with binary protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

Implemented in Network::LocalSocket, Network::NetSocket, Network::TcpSocket, and Network::UdpSocket.

void Network::Socket::_set_timeout ( bool  enable,
int  socket,
int  timeout 
) [protected]

set a timeout on a socket

Parameters:
timeoutis in second
Exceptions:
Timeoutwhen there is a timeout
SelectErrorwhen select libc function return a negative value

Definition at line 272 of file socket.cc.

References HERE.

Referenced by Network::NetSocket::_read_line(), Network::NetSocket::read(), Network::LocalSocket::read(), Network::NetSocket::readn(), and Network::LocalSocket::readn().

  {
    fd_set              fdset;
    struct timeval      timetowait;
    int         res;

    if (enable)
      timetowait.tv_sec = timeout;
    else
      timetowait.tv_sec = 65535;
    timetowait.tv_usec = 0;
    FD_ZERO(&fdset);
    FD_SET(socket, &fdset);
    if (enable)
      res = select(socket + 1, &fdset, NULL, NULL, &timetowait);
    else
      res = select(socket + 1, &fdset, NULL, NULL, NULL);
    if (res < 0)
      throw SelectError("Select error", HERE);
    if (res == 0)
      throw Timeout("Timeout on socket", HERE);
  }
bool Network::Socket::_update_buffer ( std::pair< int, int > &  delim,
int &  i,
std::string &  str 
) [inline, protected]

look delimiter and remove delimiter at begining of buffer if needed

Definition at line 45 of file socket.hxx.

References _buffer, _empty_lines, and _find_delim().

Referenced by Network::NetSocket::_read_line(), and Network::LocalSocket::_read_line().

  {
    delim = _find_delim(_buffer, 0);
    i = delim.first;
    while (!_empty_lines && !i)
      {
        // remove delimiter in front of buffer
        _buffer = _buffer.substr(delim.second, _buffer.size() - delim.second);
        delim = _find_delim(_buffer, 0);
        i = delim.first;
      }
    if ((i > 0 || _empty_lines) && ((unsigned int)i < _buffer.size()))
      {
        str = _buffer.substr(0, i);
        _buffer = _buffer.substr(i + delim.second, 
                                 _buffer.size() - i - delim.second);
        return true;
      }
    else 
      return false;
  }
void Network::Socket::_write_str ( int  socket,
const std::string &  str 
) const [protected]

Write a string to a socket (when used with textual protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

Definition at line 198 of file socket.cc.

References _addr, _tls, _version, HERE, SENDTO_FLAGS, and Network::V4.

Referenced by write().

  {
    int                         res = 1;
    unsigned int                count = 0;
    const char                  *buf;

    buf = str.c_str();
    if (socket < 0)
      throw NoConnection("No Socket", HERE);
    while (res && count < str.size())
      {
#ifdef IPV6_ENABLED
        if (V4 == _version)
#endif
#ifdef TLS
          if (_tls)
            res = gnutls_record_send(_session, buf + count, str.size() - count);
          else
#endif
            res = sendto(socket, buf + count, str.size() - count, SENDTO_FLAGS,
                         (const struct sockaddr*)&_addr, sizeof(_addr));
#ifdef IPV6_ENABLED
        else
          res = sendto(socket, buf + count, str.size() - count, SENDTO_FLAGS,
                       (const struct sockaddr*)&_addr6, sizeof(_addr6));
#endif
        if (res <= 0)
          throw ConnectionClosed("Connection Closed", HERE);
        count += res;
      }
  }
void Network::Socket::_write_str_bin ( int  socket,
const std::string &  str 
) const [protected]

Write a string to a socket (when used with binary protocol)

Exceptions:
NoConnectionwhen there is no open socket
ConnectionClosedwhen there is no more connection.

Definition at line 230 of file socket.cc.

References _addr, _tls, _version, HERE, SENDTO_FLAGS, and Network::V4.

Referenced by write().

  {
    int                         res = 1;
    unsigned int                count = 0;
#ifdef LIBSOCKET_WIN
    char*                       buf = new char[str.size() + 2];
#else
    char                        buf[str.size() + 2];
#endif
    buf[0] = str.size() / 256;
    buf[1] = str.size() % 256;
    memcpy(buf + 2, str.c_str(), str.size());
    if (socket < 0)
      throw NoConnection("No Socket", HERE);
    while (res && count < str.size() + 2)
      {
#ifdef IPV6_ENABLED
        if (V4 == _version)
#endif
#ifdef TLS
          if (_tls)
            res = gnutls_record_send(_session, buf + count, str.size() + 2 - count);
          else
#endif
            res = sendto(socket, buf + count, str.size() + 2 - count, 
                         SENDTO_FLAGS,
                         (const struct sockaddr*)&_addr, sizeof(_addr));
#ifdef IPV6_ENABLED
        else
          res = sendto(socket, buf + count, str.size() + 2 - count, 
                       \   SENDTO_FLAGS,
                       (const struct sockaddr*)&_addr6, sizeof(_addr6));
#endif
        if (res <= 0)
          throw ConnectionClosed("Connection Closed", HERE);
        count += res;
      }
#ifdef LIBSOCKET_WIN
    delete[] buf;
#endif
  }
void Network::Socket::add_delim ( const std::string &  delim)

set the delimitor for the text mode

Definition at line 318 of file socket.cc.

References _delim.

  {
    _delim.push_back(delim);
  }
void Network::Socket::allow_empty_lines ( )

, if set, empty lines will be returned in text procols (if not, they are skipped)

Definition at line 308 of file socket.cc.

References _empty_lines.

  {
    _empty_lines = true;
  }
bool Network::Socket::connected ( ) const

return true when socket is connected

Definition at line 303 of file socket.cc.

References _socket.

Referenced by enable_tls().

  {
    return _socket != 0;
  }
void Network::Socket::del_delim ( const std::string &  delim)

delete this delimitor for the socket

Definition at line 323 of file socket.cc.

References _delim.

  {
    std::list<std::string>::iterator    it, it2;

    for (it = _delim.begin(); it != _delim.end(); )
      {
        if (*it == delim)
          {
            it2 = it++;
            _delim.erase(it2);
          }
        else
          it++;
      }
  }
void Network::Socket::enable_tls ( )

Enable TLS on socket.

Definition at line 69 of file socket.cc.

References _kind, _socket, connected(), HERE, and Network::TCP.

Referenced by Network::TcpSocket::accept().

  {
#ifdef TLS
    int         ret;

    if (_kind != TCP)
      throw TLSError("You need to have a TCP connection", HERE);
    if (!connected())
      throw NoConnection("You need to have a connection", HERE);
    
    gnutls_transport_set_ptr(_session, (gnutls_transport_ptr)_socket);
    ret = gnutls_handshake(_session);
    if (ret < 0)
      {
        close(_socket);
        gnutls_deinit(_session);
        throw TLSError(gnutls_strerror(ret), HERE);
      }
#else
    throw TLSSupportError("lib was not compiled with TLS support", HERE);
#endif
  }
int Network::Socket::get_socket ( )

get socket (fd) warning: be very carefull with this method

Definition at line 313 of file socket.cc.

References _socket.

  {
    return _socket;
  }
void Network::Socket::init_tls ( GnuTLSKind  kind,
unsigned  size = 1024,
const std::string &  certfile = "",
const std::string &  keyfile = "",
const std::string &  trustfile = "",
const std::string &  crlfile = "" 
)

Exceptions:
TLSSupportErrorwhen TLS is not enabled

Definition at line 92 of file socket.cc.

References _tls, and HERE.

  {
#ifdef TLS
    static bool                                 init = false;
    static gnutls_dh_params                     dh_params;
    const int protocol_tls[] = { GNUTLS_TLS1, 0 };
    const int protocol_ssl[] = { GNUTLS_SSL3, 0 };
    const int cert_type_priority[] = { GNUTLS_CRT_X509, 
                                       GNUTLS_CRT_OPENPGP, 0 };

    if (!init)
      {
        gnutls_global_init();
        init = true;
      }
    _tls = true;
    _tls_main = true;
    gnutls_certificate_allocate_credentials(&_x509_cred);
    if (keyfile.size() > 0 && certfile.size() > 0)
      {
        std::ifstream key(keyfile.c_str()), cert(certfile.c_str());
        if (!key.is_open() || !cert.is_open())
          throw InvalidFile("key or cert invalid", HERE);
        key.close();
        cert.close();
        // Only for server...
        _nbbits = size;
        if (trustfile.size() > 0)
          gnutls_certificate_set_x509_trust_file(_x509_cred, trustfile.c_str(), 
                                                 GNUTLS_X509_FMT_PEM);
        if (crlfile.size() > 0)
          gnutls_certificate_set_x509_crl_file(_x509_cred, crlfile.c_str(), 
                                               GNUTLS_X509_FMT_PEM);
        gnutls_certificate_set_x509_key_file(_x509_cred, certfile.c_str(), 
                                             keyfile.c_str(), 
                                             GNUTLS_X509_FMT_PEM);
        gnutls_dh_params_init(&dh_params);
        gnutls_dh_params_generate2(dh_params, _nbbits);
        gnutls_certificate_set_dh_params(_x509_cred, dh_params);

        if (gnutls_init(&_session, GNUTLS_SERVER))
          throw TLSError("gnutls_init failed", HERE);
      }
    else
      {
        if (gnutls_init(&_session, GNUTLS_CLIENT))
          throw TLSError("gnutls_init failed", HERE);
      }
    
    gnutls_set_default_priority(_session);
    if (kind == TLS)
      gnutls_protocol_set_priority(_session, protocol_tls);
    else
      gnutls_protocol_set_priority(_session, protocol_ssl);

    if (keyfile.size() > 0 && certfile.size() > 0)
      {
        gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, _x509_cred);
        gnutls_certificate_server_set_request(_session, GNUTLS_CERT_REQUEST);
        gnutls_dh_set_prime_bits(_session, _nbbits);
      }
    else
      {
        gnutls_certificate_type_set_priority(_session, cert_type_priority);
        gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, _x509_cred);
      }
#else
    throw TLSSupportError("lib was not compiled with TLS support", HERE);
#endif
  }
virtual std::string Network::Socket::read ( ) [pure virtual]

function used by >> operator (read a string on current socket)

Implemented in Network::LocalSocket, and Network::NetSocket.

Referenced by Network::operator>>().

virtual std::string Network::Socket::read ( int  timeout) [pure virtual]

read a string with a timeout

Implemented in Network::LocalSocket, and Network::NetSocket.

virtual std::string Network::Socket::readn ( unsigned int  size) [pure virtual]

read a string from socket

Parameters:
sizerepresente the number of byte to read

Implemented in Network::LocalSocket, and Network::NetSocket.

virtual std::string Network::Socket::readn ( int  timeout,
unsigned int  size 
) [pure virtual]

read a string with a timeout

Parameters:
sizerepresente the number of byte to read

Implemented in Network::LocalSocket, and Network::NetSocket.

void Network::Socket::write ( const std::string &  str)

function used by << operator (write a string on current socket)

Definition at line 295 of file socket.cc.

References _proto_kind, _socket, _write_str(), _write_str_bin(), and Network::binary.

Referenced by Network::operator<<().

  {
    if (_proto_kind == binary)
      _write_str_bin(_socket, str);
    else
      _write_str(_socket, str);
  }

Member Data Documentation

std::list<std::string> Network::Socket::_delim [protected]

Definition at line 200 of file socket.hh.

Referenced by _find_delim(), add_delim(), del_delim(), and Socket().

Definition at line 201 of file socket.hh.

Referenced by _update_buffer(), and allow_empty_lines().

Definition at line 194 of file socket.hh.


The documentation for this class was generated from the following files: