tcpsocket.cc
Go to the documentation of this file.
/*
** tcpsocket.cc
** Login : Julien Lemoine <speedblue@happycoders.org>
** Started on Sun Mar 2 01:18:46 2003 Julien Lemoine
** $Id: tcpsocket.cc,v 1.6 2004/11/14 19:37:46 speedblue Exp $
**
** Copyright (C) 2003,2004 Julien Lemoine
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tcpsocket.hh"
namespace Network
{
void TcpSocket::connect(const std::string& hostname, int port)
{
_port = port;
_socket = _bind(port, hostname);
_connect(_socket, port, hostname);
}
void TcpSocket::connect(int port)
{
_port = port;
_socket = _bind(port);
_listen(_socket);
}
TcpSocket* TcpSocket::accept() const
{
TcpSocket* res;
#ifdef IPV6_ENABLED
if (V4 == _version)
#endif
res = new TcpSocket(_accept(_port, _socket));
#ifdef IPV6_ENABLED
else
res = new TcpSocket(_accept(_port, _socket), V6);
#endif
res->_port = _port;
res->_proto_kind = _proto_kind;
#ifdef TLS
if (_tls)
{
res->_tls = true;
res->_tls_main = false;
res->_session = _session;
res->_x509_cred = _x509_cred;
res->enable_tls();
}
#endif
return res;
}
std::string TcpSocket::get_ip(TcpSocket *client) const
{
return _get_ip(_port, client->_socket);
}
void TcpSocket::close()
{
if (_socket > 0)
_close(_socket);
_socket = 0;
}
std::string TcpSocket::_read_line_bin(int socket, unsigned int psize)
{
char chr[MAXPKTSIZE];
std::string str = "";
int res = 1;
unsigned int size = 0, read = 0;
bool end = false;
if (socket < 0)
throw NoConnection("No Socket", HERE);
if (_buffer.size() >= 2 && !psize)
{
size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
str = _buffer.substr(2, size);
if (_buffer.size() > size + 2)
_buffer = _buffer.substr(size + 2, _buffer.size() - size - 2);
else
_buffer = "";
read = str.size();
}
if (psize && _buffer.size() >= psize)
{
str = _buffer.substr(0, psize);
_buffer = _buffer.substr(psize, _buffer.size() - psize);
return str;
}
else if (!psize)
{
// _buffer.size() is 0 or 1
#ifdef TLS
if (_tls)
res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
else
#endif
res = recv(socket, chr, 2 - _buffer.size(), 0);
if (res <= 1)
throw ConnectionClosed("Connection Closed", HERE);
if (_buffer.size())
size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
else
size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
_buffer = "";
}
else
{
// _buffer contains less characters than size, so copy
// _bufer in str and clear _buffer.
str = _buffer;
_buffer = "";
size = psize;
read = str.size();
}
while (!end)
{
memset(chr, 0, MAXPKTSIZE);
#ifdef TLS
if (_tls)
res = gnutls_record_recv(_session, chr, size - read);
else
#endif
res = recv(socket, chr, size - read, 0);
if (res <= 0)
throw ConnectionClosed("Connection Closed", HERE);
str += std::string(chr, res).substr(0, res);
read += res;
if (read >= size)
end = true;
}
return str;
}
std::string TcpSocket::_read_line_bin(int socket, int& port,
std::string& host,
unsigned int psize)
{
char chr[MAXPKTSIZE];
std::string str = "";
int res = 1;
struct sockaddr_in addr;
#ifdef IPV6_ENABLED
struct sockaddr_in6 addr6;
#endif
#ifdef LIBSOCKET_WIN
int size;
#else
socklen_t size;
#endif
bool end = false;
unsigned int pkg_size = 0, read = 0;
#ifdef IPV6_ENABLED
if (V4 == _version)
#endif
size = sizeof(addr);
#ifdef IPV6_ENABLED
else
size = sizeof(addr6);
#endif
if (socket < 0)
throw NoConnection("No Socket", HERE);
if (_buffer.size() >= 2 && !psize)
{
pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)_buffer[1];
str = _buffer.substr(2, pkg_size);
if (_buffer.size() > pkg_size + 2)
_buffer = _buffer.substr(pkg_size + 2, _buffer.size() - pkg_size - 2);
else
_buffer = "";
read = str.size();
}
if (psize && _buffer.size() >= psize)
{
str = _buffer.substr(0, psize);
_buffer = _buffer.substr(psize, _buffer.size() - psize);
return str;
}
else if (!psize)
{
// _buffer.size() is 0 or 1
#ifdef TLS
if (_tls)
res = gnutls_record_recv(_session, chr, 2 - _buffer.size());
else
#endif
res = recv(socket, chr, 2 - _buffer.size(), 0);
if (res <= 1)
throw ConnectionClosed("Connection Closed", HERE);
if (_buffer.size())
pkg_size = (unsigned char)_buffer[0] * 256 + (unsigned char)chr[0];
else
pkg_size = (unsigned char)chr[0] * 256 + (unsigned char)chr[1];
_buffer = "";
}
else
{
// _buffer contains less characters than size, so copy
// _bufer in str and clear _buffer.
str = _buffer;
_buffer = "";
pkg_size = psize;
read = str.size();
}
while (!end)
{
#ifdef TLS
if (_tls)
res = gnutls_record_recv(_session, chr, size - read);
else
#endif
res = recv(socket, chr, size - read, 0);
#ifdef IPV6_ENABLED
if (V4 == _version)
#endif
if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0)
throw GetpeernameError("getpeername error", HERE);
#ifdef IPV6_ENABLED
else
if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0)
throw GetpeernameError("getpeername error", HERE);
#endif
if (res <= 0)
throw ConnectionClosed("Connection Closed", HERE);
str += std::string(chr, res).substr(0, res);
read += res;
if (read >= pkg_size)
end = true;
}
#ifdef IPV6_ENABLED
if (V4 == _version)
{
#endif
host = std::string(inet_ntoa(addr.sin_addr));
port = ntohs(addr.sin_port);
#ifdef IPV6_ENABLED
}
else
{
char buf[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
throw InetntopError("Not a valid address", HERE);
host = std::string(buf);
port = ntohs(addr6.sin6_port);
}
#endif
return str;
}
}
Network::NetSocket::_bind
int _bind(int port, const std::string &host)
Bind a UDP server.
Definition netsocket.cc:86
Network::NetSocket::_port
int _port
Definition netsocket.hh:161
Network::NetSocket::_get_ip
std::string _get_ip(int port, int socket) const
Get Client Ip.
Definition netsocket.cc:243
Network::NetSocket::_connect
void _connect(int socket, int port, const std::string &host) const
Connect to a hostname.
Definition netsocket.cc:186
Network::NetSocket::_accept
int _accept(int port, int server_socket) const
Wait for a client.
Definition netsocket.cc:211
Network::NetSocket::read
std::string read()
function used by >> operator (read a string on current socket)
Definition netsocket.cc:533
Network::Socket::_tls
bool _tls
Definition socket.hh:203
Network::Socket::_buffer
std::string _buffer
Definition socket.hh:202
Network::Socket::enable_tls
void enable_tls()
Enable TLS on socket.
Definition socket.cc:69
Network::Socket::_socket
int _socket
Definition socket.hh:193
Network::Socket::_version
SOCKET_VERSION _version
Definition socket.hh:191
Network::Socket::_listen
void _listen(int socket) const
Listen on port.
Definition socket.cc:192
Network::Socket::_close
void _close(int socket) const
Close a connnection.
Definition socket.cc:167
Network::Socket::_proto_kind
PROTO_KIND _proto_kind
Definition socket.hh:199
Network::TcpSocket
This class represent a tcp connection (client and server)
Definition tcpsocket.hh:33
Network::TcpSocket::get_ip
std::string get_ip(TcpSocket *client) const
return ip of client (after an accept)
Definition tcpsocket.cc:69
Network::TcpSocket::close
void close()
Close the connection.
Definition tcpsocket.cc:74
Network::TcpSocket::accept
TcpSocket * accept() const
accept a new client (For server only)
Definition tcpsocket.cc:42
Network::TcpSocket::connect
void connect(const std::string &hostname, int port)
Connect as an TCP client.
Definition tcpsocket.cc:28
Network::TcpSocket::_read_line_bin
std::string _read_line_bin(int socket, int &port, std::string &host, unsigned int psize)
Get a line from socket and store client hostname and port in port and host variable (when used with b...
Definition tcpsocket.cc:152
Network
Network namespace represent all networks connection.
Definition localsocket.cc:33
Network::V4
@ V4
Definition socket.hh:87
Network::V6
@ V6
Definition socket.hh:88
HERE
#define HERE
Definition socketexception.hh:26
tcpsocket.hh