Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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="")
 TLSSupportError when 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.
void _listen (int socket) const
 Listen on port.
virtual std::string _read_line (int socket)=0
 Get a line from socket (when used with textual protocol).
virtual std::string _read_line_bin (int socket, unsigned int size)=0
 Get a line from socket (when used with binary protocol).
void _write_str (int socket, const std::string &str) const
 Write a string to a socket (when used with textual protocol).
void _write_str_bin (int socket, const std::string &str) const
 Write a string to a socket (when used with binary protocol).
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 Socket::_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
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 99 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, Network::text, and Network::V6.

00031                                                          :
00032     _kind(kind), _version(version), _state_timeout(0),
00033     _socket(0), _recv_flags(kind), _proto_kind(text), _empty_lines(false),
00034     _buffer(""), _tls(false)
00035   {
00036     _delim.push_back("\0");
00037 #ifdef LIBSOCKET_WIN
00038     WSADATA wsadata;
00039     if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0)
00040       throw WSAStartupError("WSAStartup failed", HERE);
00041 #endif
00042 #ifndef IPV6_ENABLED
00043     if (version == V6)
00044       throw Ipv6SupportError("lib was not compiled with ipv6 support", HERE);
00045 #endif
00046   }

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.

00048                                                                            :
00049     _kind(kind), _version(version), _state_timeout(0),
00050     _socket(0), _recv_flags(kind), _proto_kind(pkind), _empty_lines(false),
00051     _buffer(""), _tls(false)
00052   {
00053     _delim.push_back("\0");
00054 #ifdef LIBSOCKET_WIN
00055     WSADATA wsadata;
00056     if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0)
00057       throw WSAStartupError("WSAStartup failed", HERE);
00058 #endif
00059 #ifndef IPV6_ENABLED
00060     if (version == V6)
00061       throw Ipv6SupportError("lib was not compiled with ipv6 support", HERE);
00062 #endif
00063   }

Network::Socket::~Socket  )  [virtual]
 

Definition at line 65 of file socket.cc.

00066   {
00067   }


Member Function Documentation

void Network::Socket::_close int  socket  )  const [protected]
 

Close a connnection.

Exceptions:
CloseException when 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().

00168   {
00169 #ifndef LIBSOCKET_WIN
00170     if (socket < 0 || close(socket) < 0)
00171       throw CloseError("Close Error", HERE);
00172     socket = 0;
00173 #endif
00174 #ifdef TLS
00175     if (_tls)
00176       {
00177         std::cout << "Deletion..." << std::endl;
00178         gnutls_deinit(_session);
00179         if (_tls_main)
00180           {
00181             gnutls_certificate_free_credentials(_x509_cred);
00182             gnutls_global_deinit();
00183           }
00184       }
00185 #endif
00186   }

std::pair< int, int > Network::Socket::_find_delim const std::string &  str,
int  start
const [protected]
 

Definition at line 335 of file socket.cc.

References _delim.

Referenced by _update_buffer().

00336   {
00337     int                                         i = -1;
00338     int                                         pos = -1, size = 0;
00339     std::list<std::string>::const_iterator      it;
00340 
00341     // Looking for the first delimiter.
00342     if (_delim.size() > 0)
00343       {
00344         it = _delim.begin();
00345         while (it != _delim.end())
00346           {
00347             if (*it == "")
00348               i = str.find('\0', start);
00349             else
00350               i = str.find(*it, start);
00351             if ((i >= 0) && ((unsigned int)i < str.size()) &&
00352                 (pos < 0 || i < pos))
00353               {
00354                 pos = i;
00355                 size = it->size() ? it->size() : 1;
00356               }
00357             it++;
00358           }
00359       }
00360     return std::pair<int, int>(pos, size);
00361   }

void Network::Socket::_listen int  socket  )  const [protected]
 

Listen on port.

Exceptions:
ListenException when listen libc function return a negative value

Definition at line 188 of file socket.cc.

References HERE.

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

00189   {
00190     if (socket < 0 || listen(socket, 5) < 0)
00191       throw ListenError("Listen Error", HERE);
00192   }

virtual std::string Network::Socket::_read_line int  socket  )  [protected, pure virtual]
 

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

Exceptions:
NoConnection when there is no open socket
ConnectionClosed when 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:
NoConnection when there is no open socket
ConnectionClosed when 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:
timeout is in second
Exceptions:
Timeout when there is a timeout
SelectError when select libc function return a negative value

Definition at line 268 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().

00269   {
00270     fd_set              fdset;
00271     struct timeval      timetowait;
00272     int         res;
00273 
00274     if (enable)
00275       timetowait.tv_sec = timeout;
00276     else
00277       timetowait.tv_sec = 65535;
00278     timetowait.tv_usec = 0;
00279     FD_ZERO(&fdset);
00280     FD_SET(socket, &fdset);
00281     if (enable)
00282       res = select(socket + 1, &fdset, NULL, NULL, &timetowait);
00283     else
00284       res = select(socket + 1, &fdset, NULL, NULL, NULL);
00285     if (res < 0)
00286       throw SelectError("Select error", HERE);
00287     if (res == 0)
00288       throw Timeout("Timeout on socket", HERE);
00289   }

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().

00047   {
00048     delim = _find_delim(_buffer, 0);
00049     i = delim.first;
00050     while (!_empty_lines && !i)
00051       {
00052         // remove delimiter in front of buffer
00053         _buffer = _buffer.substr(delim.second, _buffer.size() - delim.second);
00054         delim = _find_delim(_buffer, 0);
00055         i = delim.first;
00056       }
00057     if ((i > 0 || _empty_lines) && ((unsigned int)i < _buffer.size()))
00058       {
00059         str = _buffer.substr(0, i);
00060         _buffer = _buffer.substr(i + delim.second, 
00061                                  _buffer.size() - i - delim.second);
00062         return true;
00063       }
00064     else 
00065       return false;
00066   }

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:
NoConnection when there is no open socket
ConnectionClosed when there is no more connection

Definition at line 194 of file socket.cc.

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

Referenced by write().

00195   {
00196     int                         res = 1;
00197     unsigned int                count = 0;
00198     const char                  *buf;
00199 
00200     buf = str.c_str();
00201     if (socket < 0)
00202       throw NoConnection("No Socket", HERE);
00203     while (res && count < str.size())
00204       {
00205 #ifdef IPV6_ENABLED
00206         if (V4 == _version)
00207 #endif
00208 #ifdef TLS
00209           if (_tls)
00210             res = gnutls_record_send(_session, buf + count, str.size() - count);
00211           else
00212 #endif
00213             res = sendto(socket, buf + count, str.size() - count, SENDTO_FLAGS,
00214                          (const struct sockaddr*)&_addr, sizeof(_addr));
00215 #ifdef IPV6_ENABLED
00216         else
00217           res = sendto(socket, buf + count, str.size() - count, SENDTO_FLAGS,
00218                        (const struct sockaddr*)&_addr6, sizeof(_addr6));
00219 #endif
00220         if (res <= 0)
00221           throw ConnectionClosed("Connection Closed", HERE);
00222         count += res;
00223       }
00224   }

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:
NoConnection when there is no open socket
ConnectionClosed when there is no more connection

Definition at line 226 of file socket.cc.

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

Referenced by write().

00227   {
00228     int                         res = 1;
00229     unsigned int                count = 0;
00230 #ifdef LIBSOCKET_WIN
00231     char*                       buf = new char[str.size() + 2];
00232 #else
00233     char                        buf[str.size() + 2];
00234 #endif
00235     buf[0] = str.size() / 256;
00236     buf[1] = str.size() % 256;
00237     memcpy(buf + 2, str.c_str(), str.size());
00238     if (socket < 0)
00239       throw NoConnection("No Socket", HERE);
00240     while (res && count < str.size() + 2)
00241       {
00242 #ifdef IPV6_ENABLED
00243         if (V4 == _version)
00244 #endif
00245 #ifdef TLS
00246           if (_tls)
00247             res = gnutls_record_send(_session, buf + count, str.size() + 2 - count);
00248           else
00249 #endif
00250             res = sendto(socket, buf + count, str.size() + 2 - count, 
00251                          SENDTO_FLAGS,
00252                          (const struct sockaddr*)&_addr, sizeof(_addr));
00253 #ifdef IPV6_ENABLED
00254         else
00255           res = sendto(socket, buf + count, str.size() + 2 - count, 
00256                        \   SENDTO_FLAGS,
00257                        (const struct sockaddr*)&_addr6, sizeof(_addr6));
00258 #endif
00259         if (res <= 0)
00260           throw ConnectionClosed("Connection Closed", HERE);
00261         count += res;
00262       }
00263 #ifdef LIBSOCKET_WIN
00264     delete[] buf;
00265 #endif
00266   }

void Network::Socket::add_delim const std::string &  delim  ) 
 

set the delimitor for the text mode

Definition at line 314 of file socket.cc.

References _delim.

00315   {
00316     _delim.push_back(delim);
00317   }

void Network::Socket::allow_empty_lines  ) 
 

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

Definition at line 304 of file socket.cc.

References _empty_lines.

00305   {
00306     _empty_lines = true;
00307   }

bool Network::Socket::connected  )  const
 

return true when socket is connected

Definition at line 299 of file socket.cc.

References _socket.

Referenced by enable_tls().

00300   {
00301     return _socket != 0;
00302   }

void Network::Socket::del_delim const std::string &  delim  ) 
 

delete this delimitor for the socket

Definition at line 319 of file socket.cc.

References _delim.

00320   {
00321     std::list<std::string>::iterator    it, it2;
00322 
00323     for (it = _delim.begin(); it != _delim.end(); )
00324       {
00325         if (*it == delim)
00326           {
00327             it2 = it++;
00328             _delim.erase(it2);
00329           }
00330         else
00331           it++;
00332       }
00333   }

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.

00070   {
00071 #ifdef TLS
00072     int         ret;
00073 
00074     if (_kind != TCP)
00075       throw TLSError("You need to have a TCP connection", HERE);
00076     if (!connected())
00077       throw NoConnection("You need to have a connection", HERE);
00078     
00079     gnutls_transport_set_ptr(_session, (gnutls_transport_ptr)_socket);
00080     ret = gnutls_handshake(_session);
00081     if (ret < 0)
00082       {
00083         close(_socket);
00084         gnutls_deinit(_session);
00085         throw TLSError(gnutls_strerror(ret), HERE);
00086       }
00087 #else
00088     throw TLSSupportError("lib was not compiled with TLS support", HERE);
00089 #endif
00090   }

int Network::Socket::get_socket  ) 
 

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

Definition at line 309 of file socket.cc.

References _socket.

00310   {
00311     return _socket;
00312   }

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 = ""
 

TLSSupportError when TLS is not enabled.

Definition at line 92 of file socket.cc.

References _tls, and HERE.

00097   {
00098 #ifdef TLS
00099     static bool                                 init = false;
00100     static gnutls_dh_params                     dh_params;
00101     const int protocol_tls[] = { GNUTLS_TLS1, 0 };
00102     const int protocol_ssl[] = { GNUTLS_SSL3, 0 };
00103     const int cert_type_priority[] = { GNUTLS_CRT_X509, 
00104                                        GNUTLS_CRT_OPENPGP, 0 };
00105 
00106     if (!init)
00107       {
00108         gnutls_global_init();
00109         init = true;
00110       }
00111     _tls = true;
00112     _tls_main = true;
00113     gnutls_certificate_allocate_credentials(&_x509_cred);
00114     if (keyfile.size() > 0 && certfile.size() > 0)
00115       {
00116         std::ifstream key(keyfile.c_str()), cert(certfile.c_str());
00117         if (!key.is_open() || !cert.is_open())
00118           throw InvalidFile("key or cert invalid", HERE);
00119         key.close();
00120         cert.close();
00121         // Only for server...
00122         _nbbits = size;
00123         if (trustfile.size() > 0)
00124           gnutls_certificate_set_x509_trust_file(_x509_cred, trustfile.c_str(), 
00125                                                  GNUTLS_X509_FMT_PEM);
00126         if (crlfile.size() > 0)
00127           gnutls_certificate_set_x509_crl_file(_x509_cred, crlfile.c_str(), 
00128                                                GNUTLS_X509_FMT_PEM);
00129         gnutls_certificate_set_x509_key_file(_x509_cred, certfile.c_str(), 
00130                                              keyfile.c_str(), 
00131                                              GNUTLS_X509_FMT_PEM);
00132         gnutls_dh_params_init(&dh_params);
00133         gnutls_dh_params_generate2(dh_params, _nbbits);
00134         gnutls_certificate_set_dh_params(_x509_cred, dh_params);
00135 
00136         if (gnutls_init(&_session, GNUTLS_SERVER))
00137           throw TLSError("gnutls_init failed", HERE);
00138       }
00139     else
00140       {
00141         if (gnutls_init(&_session, GNUTLS_CLIENT))
00142           throw TLSError("gnutls_init failed", HERE);
00143       }
00144     
00145     gnutls_set_default_priority(_session);
00146     if (kind == TLS)
00147       gnutls_protocol_set_priority(_session, protocol_tls);
00148     else
00149       gnutls_protocol_set_priority(_session, protocol_ssl);
00150 
00151     if (keyfile.size() > 0 && certfile.size() > 0)
00152       {
00153         gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, _x509_cred);
00154         gnutls_certificate_server_set_request(_session, GNUTLS_CERT_REQUEST);
00155         gnutls_dh_set_prime_bits(_session, _nbbits);
00156       }
00157     else
00158       {
00159         gnutls_certificate_type_set_priority(_session, cert_type_priority);
00160         gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, _x509_cred);
00161       }
00162 #else
00163     throw TLSSupportError("lib was not compiled with TLS support", HERE);
00164 #endif
00165   }

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::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::readn int  timeout,
unsigned int  size
[pure virtual]
 

read a string with a timeout

Parameters:
size represente the number of byte to read

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

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

read a string from socket

Parameters:
size represente the number of byte to read

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

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

return the content of the buffer is there is

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

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

Definition at line 291 of file socket.cc.

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

Referenced by Network::operator<<().

00292   {
00293     if (_proto_kind == binary)
00294       _write_str_bin(_socket, str);
00295     else
00296       _write_str(_socket, str);
00297   }


Member Data Documentation

struct sockaddr_in Network::Socket::_addr [protected]
 

Definition at line 194 of file socket.hh.

Referenced by _write_str(), and _write_str_bin().

std::string Network::Socket::_buffer [protected]
 

Definition at line 201 of file socket.hh.

Referenced by _update_buffer().

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

Definition at line 199 of file socket.hh.

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

bool Network::Socket::_empty_lines [protected]
 

Definition at line 200 of file socket.hh.

Referenced by _update_buffer(), and allow_empty_lines().

SOCKET_KIND Network::Socket::_kind [protected]
 

Definition at line 189 of file socket.hh.

Referenced by enable_tls().

PROTO_KIND Network::Socket::_proto_kind [protected]
 

Definition at line 198 of file socket.hh.

Referenced by write().

int Network::Socket::_recv_flags [protected]
 

Definition at line 193 of file socket.hh.

int Network::Socket::_socket [protected]
 

Definition at line 192 of file socket.hh.

Referenced by connected(), enable_tls(), get_socket(), and write().

unsigned Network::Socket::_state_timeout [protected]
 

Definition at line 191 of file socket.hh.

bool Network::Socket::_tls [protected]
 

Definition at line 202 of file socket.hh.

Referenced by _close(), _write_str(), _write_str_bin(), and init_tls().

SOCKET_VERSION Network::Socket::_version [protected]
 

Definition at line 190 of file socket.hh.

Referenced by _write_str(), and _write_str_bin().


The documentation for this class was generated from the following files:
Generated on Fri Apr 8 06:13:01 2005 for libsocket by  doxygen 1.4.0