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

tcpsocket.cc

Go to the documentation of this file.
00001 /*
00002 ** tcpsocket.cc
00003 ** Login : Julien Lemoine <speedblue@happycoders.org>
00004 ** Started on  Sun Mar  2 01:18:46 2003 Julien Lemoine
00005 ** $Id: tcpsocket.cc,v 1.5 2004/06/06 14:13:56 speedblue Exp $
00006 **
00007 ** Copyright (C) 2003,2004 Julien Lemoine
00008 ** This program is free software; you can redistribute it and/or modify
00009 ** it under the terms of the GNU Lesser General Public License as published by
00010 ** the Free Software Foundation; either version 2 of the License, or
00011 ** (at your option) any later version.
00012 **
00013 ** This program is distributed in the hope that it will be useful,
00014 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 ** GNU Lesser General Public License for more details.
00017 **
00018 ** You should have received a copy of the GNU Lesser General Public License
00019 ** along with this program; if not, write to the Free Software
00020 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00021 */
00022 
00023 #include "tcpsocket.hh"
00024 
00025 namespace Network
00026 {
00027 
00028   void  TcpSocket::connect(const std::string& hostname, int port)
00029   {
00030     _port = port;
00031     _socket = _bind(port, hostname);
00032     _connect(_socket, port, hostname);
00033   }
00034 
00035   void  TcpSocket::connect(int port)
00036   {
00037     _port = port;
00038     _socket = _bind(port);
00039     _listen(_socket);
00040   }
00041 
00042   TcpSocket*    TcpSocket::accept() const
00043   {
00044     TcpSocket* res;
00045 
00046 #ifdef IPV6_ENABLED
00047     if (V4 == _version)
00048 #endif
00049       res = new TcpSocket(_accept(_port, _socket));
00050 #ifdef IPV6_ENABLED
00051     else
00052       res = new TcpSocket(_accept(_port, _socket), V6);
00053 #endif
00054     res->_port = _port;
00055     res->_proto_kind = _proto_kind;
00056 #ifdef TLS
00057     if (_tls)
00058       {
00059         res->_tls = true;
00060         res->_tls_main = false;
00061         res->_session = _session;
00062         res->_x509_cred = _x509_cred;
00063         res->enable_tls();
00064       }
00065 #endif
00066     return res;
00067   }
00068 
00069   std::string   TcpSocket::get_ip(TcpSocket *client) const
00070   {
00071     return _get_ip(_port, client->_socket);
00072   }
00073 
00074   void  TcpSocket::close()
00075   {
00076     if (_socket > 0)
00077       _close(_socket);
00078     _socket = 0;
00079   }
00080 
00081   std::string   TcpSocket::_read_line_bin(int socket, unsigned int psize)
00082   {
00083     char                chr[MAXPKTSIZE];
00084     std::string         str = "";
00085     int                 res = 1;
00086     unsigned int        size = 0, read = 0;
00087     bool                end = false;
00088 
00089     if (socket < 0)
00090       throw NoConnection("No Socket", HERE);
00091     if (_buffer.size() >= 2 && !psize)
00092       {
00093         size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
00094         str = _buffer.substr(2, size);
00095         if (_buffer.size() > size + 2)
00096           _buffer = _buffer.substr(size + 2, _buffer.size() - size - 2);
00097         else
00098           _buffer = "";
00099         read = str.size();
00100       }
00101     if (psize && _buffer.size() >= psize)
00102       {
00103         str = _buffer.substr(0, psize);
00104         _buffer = _buffer.substr(psize, _buffer.size() - psize);
00105         return str;
00106       }
00107     else if (!psize)
00108       {
00109         // _buffer.size() is 0 or 1
00110 #ifdef TLS
00111         if (_tls)
00112           res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
00113         else
00114 #endif
00115           res = recv(socket, chr, 2 - _buffer.size(), 0);
00116         if (res <= 1)
00117           throw ConnectionClosed("Connection Closed", HERE);
00118         if (_buffer.size())
00119           size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
00120         else
00121           size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
00122         _buffer = "";
00123       }
00124     else
00125       {
00126         // _buffer contains less characters than size, so copy
00127         // _bufer in str and clear _buffer.
00128         str = _buffer;
00129         _buffer = "";
00130         size = psize;
00131         read = str.size();
00132       }
00133     while (!end)
00134       {
00135         memset(chr, 0, MAXPKTSIZE);
00136 #ifdef TLS
00137         if (_tls)
00138           res = gnutls_record_recv(_session, chr, size - read);
00139         else
00140 #endif
00141           res = recv(socket, chr, size - read, 0);
00142         if (res <= 0)
00143           throw ConnectionClosed("Connection Closed", HERE);
00144         str += std::string(chr, res).substr(0, res);
00145         read += res;
00146         if (read >= size)
00147           end = true;
00148       }
00149     return str;
00150   }
00151 
00152   std::string   TcpSocket::_read_line_bin(int socket, int& port,
00153                                           std::string& host,
00154                                           unsigned int psize)
00155   {
00156     char                        chr[MAXPKTSIZE];
00157     std::string                 str = "";
00158     int                         res = 1;
00159     struct sockaddr_in          addr;
00160 #ifdef IPV6_ENABLED
00161     struct sockaddr_in6         addr6;
00162 #endif
00163 #ifdef LIBSOCKET_WIN
00164     int                         size;
00165 #else
00166     socklen_t                   size;
00167 #endif
00168     bool                        end = false;
00169     unsigned int                pkg_size = 0, read = 0;
00170 
00171 #ifdef IPV6_ENABLED
00172     if (V4 == _version)
00173 #endif
00174       size = sizeof(addr);
00175 #ifdef IPV6_ENABLED
00176     else
00177       size = sizeof(addr6);
00178 #endif
00179     if (socket < 0)
00180       throw NoConnection("No Socket", HERE);
00181     if (_buffer.size() >= 2 && !psize)
00182       {
00183         pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
00184         str = _buffer.substr(2, pkg_size);
00185         if (_buffer.size() > pkg_size + 2)
00186           _buffer = _buffer.substr(pkg_size + 2, _buffer.size() - pkg_size - 2);
00187         else
00188           _buffer = "";
00189         read = str.size();
00190       }
00191     if (psize && _buffer.size() >= psize)
00192       {
00193         str = _buffer.substr(0, psize);
00194         _buffer = _buffer.substr(psize, _buffer.size() - psize);
00195         return str;
00196       }
00197     else if (!psize)
00198       {
00199         // _buffer.size() is 0 or 1
00200 #ifdef TLS
00201         if (_tls)
00202           res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
00203         else
00204 #endif
00205           res = recv(socket, chr, 2 - _buffer.size(), 0);
00206         if (res <= 1)
00207           throw ConnectionClosed("Connection Closed", HERE);
00208         if (_buffer.size())
00209           pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
00210         else
00211           pkg_size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
00212         _buffer = "";
00213       }
00214     else
00215       {
00216         // _buffer contains less characters than size, so copy
00217         // _bufer in str and clear _buffer.
00218         str = _buffer;
00219         _buffer = "";
00220         pkg_size = psize;
00221         read = str.size();
00222       }
00223     while (!end)
00224       {
00225 #ifdef TLS
00226         if (_tls)
00227           res = gnutls_record_recv(_session, chr, size - read);
00228         else
00229 #endif
00230           res = recv(socket, chr, size - read, 0);
00231 #ifdef IPV6_ENABLED
00232         if (V4 == _version)
00233 #endif
00234           if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0)
00235             throw GetpeernameError("getpeername error", HERE);
00236 #ifdef IPV6_ENABLED
00237         else
00238           if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0)
00239             throw GetpeernameError("getpeername error", HERE);
00240 #endif
00241         if (res <= 0)
00242           throw ConnectionClosed("Connection Closed", HERE);
00243         str += std::string(chr, res).substr(0, res);
00244         read += res;
00245         if (read >= pkg_size)
00246           end = true;
00247       }
00248 #ifdef IPV6_ENABLED
00249     if (V4 == _version)
00250       {
00251 #endif
00252         host = std::string(inet_ntoa(addr.sin_addr));
00253         port = ntohs(addr.sin_port);
00254 #ifdef IPV6_ENABLED
00255       }
00256     else
00257       {
00258         char buf[INET6_ADDRSTRLEN];
00259         if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
00260           throw InetntopError("Not a valid address", HERE);
00261         host = std::string(buf);
00262         port = ntohs(addr6.sin6_port);
00263       }
00264 #endif
00265     return str;
00266   }
00267 }

Generated on Fri Apr 8 06:13:01 2005 for libsocket by  doxygen 1.4.0