From 7e74b790d290cd7d776349503bb361c47933c01f Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 19 Nov 2003 22:52:17 +0000 Subject: [PATCH] Se emprolija un poco: - Se mejora mucho el manejo y deteccion de errores. - Tambien se mejora la informacion de debug poniendo el numero de linea. - Se pone en todos los objetos que se conectan la parte de la conexion en el constructor para que pueda capturarse una eventual excepcion. - Se crea una nueva signal_error para avisar sobre cualquier error que pase en el run() que no puede lanzar excepciones. --- Server/configure.in | 2 +- Server/include/plaqui/server/command.h | 6 +- Server/include/plaqui/server/controlclient.h | 4 +- Server/include/plaqui/server/httpheaders.h | 5 +- Server/include/plaqui/server/httprequest.h | 5 +- Server/include/plaqui/server/httpresponse.h | 6 +- Server/include/plaqui/server/receiver.h | 2 +- Server/include/plaqui/server/runnable.h | 16 ++++- Server/include/plaqui/server/server.h | 2 +- Server/include/plaqui/server/tcpserver.h | 4 +- Server/include/plaqui/server/transmitter.h | 3 +- Server/src/command.cpp | 23 ++++--- Server/src/connection.cpp | 22 +++++-- Server/src/controlclient.cpp | 51 ++++++++++----- Server/src/controlserver.cpp | 34 +++++++--- Server/src/httperror.cpp | 6 +- Server/src/httpheaders.cpp | 27 +++++--- Server/src/httpmessage.cpp | 12 ++-- Server/src/httprequest.cpp | 23 ++++--- Server/src/httpresponse.cpp | 31 +++++---- Server/src/plant.cpp | 68 +++++++++++++++----- Server/src/receiver.cpp | 23 +++++-- Server/src/runnable.cpp | 19 ++++-- Server/src/server.cpp | 33 +++++----- Server/src/tcpserver.cpp | 48 +++++++++----- Server/src/transmitter.cpp | 42 ++++++++---- Server/tests/Makefile.am | 2 +- Server/tests/client_test.cpp | 9 +++ Server/tests/server_test.cpp | 27 +++++++- 29 files changed, 383 insertions(+), 172 deletions(-) diff --git a/Server/configure.in b/Server/configure.in index fbbe7f8..8ea8f73 100644 --- a/Server/configure.in +++ b/Server/configure.in @@ -26,7 +26,7 @@ ## AC_INIT(configure.in) -AM_INIT_AUTOMAKE(plaqui_server, 0.9) +AM_INIT_AUTOMAKE(plaqui_server, 0.10) AM_MAINTAINER_MODE AC_ISC_POSIX diff --git a/Server/include/plaqui/server/command.h b/Server/include/plaqui/server/command.h index cd49d43..d27fbe2 100644 --- a/Server/include/plaqui/server/command.h +++ b/Server/include/plaqui/server/command.h @@ -28,7 +28,9 @@ #ifndef PLAQUI_COMMAND_H #define PLAQUI_COMMAND_H +#include "httperror.h" #include "httprequest.h" +#include #include #include #include @@ -127,13 +129,13 @@ namespace Server { * Obtiene el comando desde un pedido HTTP completo. */ friend std::istream& operator>>(std::istream& is, - Command& command); + Command& command) throw(HTTPError, sockerr); /** * Convierte el comando a un pedido HTTP completo. */ friend std::ostream& operator<<(std::ostream& os, - const Command& command); + const Command& command) throw(sockerr); }; diff --git a/Server/include/plaqui/server/controlclient.h b/Server/include/plaqui/server/controlclient.h index f225240..507d222 100644 --- a/Server/include/plaqui/server/controlclient.h +++ b/Server/include/plaqui/server/controlclient.h @@ -92,8 +92,8 @@ namespace Server { * control. * \param port Puerto al cual conectarse. */ - ControlClient(const std::string& host = "localhost", - const Connection::Port& port = 7522); + ControlClient(const std::string& _host = "localhost", + const Connection::Port& _port = 7522) throw(sockerr); /** * Envía un comando al servidor. diff --git a/Server/include/plaqui/server/httpheaders.h b/Server/include/plaqui/server/httpheaders.h index 86a2dd1..23470f3 100644 --- a/Server/include/plaqui/server/httpheaders.h +++ b/Server/include/plaqui/server/httpheaders.h @@ -29,6 +29,7 @@ #define PLAQUI_HTTPHEADERS_H #include "plaqui/server/httperror.h" +#include #include #include #include @@ -54,13 +55,13 @@ namespace Server { * Obtiene los datos de las cabeceras HTTP desde un texto. */ friend std::istream& operator>>(std::istream& is, HTTPHeaders& h) - throw(HTTPError); + throw(HTTPError, sockerr, ios::failure); /** * Convierte las cabeceras HTTP a texto. */ friend std::ostream& operator<<(std::ostream& os, - const HTTPHeaders& h); + const HTTPHeaders& h) throw(sockerr); }; diff --git a/Server/include/plaqui/server/httprequest.h b/Server/include/plaqui/server/httprequest.h index 5056d15..5f0757e 100644 --- a/Server/include/plaqui/server/httprequest.h +++ b/Server/include/plaqui/server/httprequest.h @@ -30,6 +30,7 @@ #include "plaqui/server/httperror.h" #include "plaqui/server/httpmessage.h" +#include #include #include #include @@ -122,13 +123,13 @@ namespace Server { * Obtiene los datos del pedido HTTP desde un texto. */ friend std::istream& operator>>(std::istream& is, HTTPRequest& req) - throw(HTTPError, std::ios::failure); + throw(HTTPError, sockerr, std::ios::failure); /** * Convierte el pedido HTTP en texto. */ friend std::ostream& operator<<(std::ostream& os, - const HTTPRequest& req); + const HTTPRequest& req) throw(sockerr); }; diff --git a/Server/include/plaqui/server/httpresponse.h b/Server/include/plaqui/server/httpresponse.h index f4a2db0..5aa8f62 100644 --- a/Server/include/plaqui/server/httpresponse.h +++ b/Server/include/plaqui/server/httpresponse.h @@ -30,6 +30,7 @@ #include "plaqui/server/httperror.h" #include "plaqui/server/httpmessage.h" +#include #include namespace PlaQui { @@ -97,13 +98,14 @@ namespace Server { * Obtiene los datos de la respuesta HTTP desde un texto. */ friend std::istream& operator>>(std::istream& is, - HTTPResponse& resp) throw(Error, std::ios::failure); + HTTPResponse& resp) + throw(Error, sockerr, std::ios::failure); /** * Convierte la respuesta HTTP en texto. */ friend std::ostream& operator<<(std::ostream& os, - const HTTPResponse& resp); + const HTTPResponse& resp) throw(sockerr); }; diff --git a/Server/include/plaqui/server/receiver.h b/Server/include/plaqui/server/receiver.h index 1ac45ef..462c739 100644 --- a/Server/include/plaqui/server/receiver.h +++ b/Server/include/plaqui/server/receiver.h @@ -90,7 +90,7 @@ namespace Server { * \param host Host del cual recibir el estado de la planta. */ Receiver(const Connection::Port& port = 7528, - const std::string& host = "localhost"); + const std::string& host = "localhost") throw(sockerr); /** * Obtiene la señal que avisa cuando se recibió un cuadro. diff --git a/Server/include/plaqui/server/runnable.h b/Server/include/plaqui/server/runnable.h index 7896090..c46cf8c 100644 --- a/Server/include/plaqui/server/runnable.h +++ b/Server/include/plaqui/server/runnable.h @@ -42,9 +42,15 @@ namespace Server { public: + /// Error. + typedef unsigned Error; + /// Tipo de señal para indicar que se finalizó la tarea. typedef SigC::Signal0 SignalFinished; + /// Tipo de señal para indicar que hubo un error. + typedef SigC::Signal2 SignalError; + // Atributos. private: @@ -57,6 +63,9 @@ namespace Server { protected: + /// Señal que indica que hubo un error. + SignalError error; + /** * Indica si se debe frinalizar la tarea. * @@ -113,11 +122,14 @@ namespace Server { /** * Obtiene la señal que avisa cuando la tarea es finalizada. - * - * \see finish(). */ SignalFinished& signal_finished(void); + /** + * Obtiene la señal que avisa que hubo un error. + */ + SignalError& signal_error(void); + }; } diff --git a/Server/include/plaqui/server/server.h b/Server/include/plaqui/server/server.h index b295483..9953fd9 100644 --- a/Server/include/plaqui/server/server.h +++ b/Server/include/plaqui/server/server.h @@ -140,7 +140,7 @@ namespace Server { * \param port Puerto en el cual escuchar. */ Server(const std::string& plant_filename, - const Connection::Port& port = 7522); + const Connection::Port& port = 7522) throw(sockerr); /** * Maneja los comandos recibidos por las conexiones. diff --git a/Server/include/plaqui/server/tcpserver.h b/Server/include/plaqui/server/tcpserver.h index 17ce3b1..a64b545 100644 --- a/Server/include/plaqui/server/tcpserver.h +++ b/Server/include/plaqui/server/tcpserver.h @@ -116,7 +116,7 @@ namespace Server { * * \param port Puerto en el cual escuchar. */ - TCPServer(const Connection::Port& port); + TCPServer(const Connection::Port& port) throw(sockerr); /** * Finaliza la tarea. @@ -127,7 +127,7 @@ namespace Server { * \note Para saber cuando la tarea fue finalizada puede utilizar * la señal signal_finished(). */ - virtual void finish(bool attach = false); + //virtual void finish(bool attach = false); /** * Se encarga de borrar una conexión de la lista cuando finaliza. diff --git a/Server/include/plaqui/server/transmitter.h b/Server/include/plaqui/server/transmitter.h index 211a31e..98957fe 100644 --- a/Server/include/plaqui/server/transmitter.h +++ b/Server/include/plaqui/server/transmitter.h @@ -64,7 +64,8 @@ namespace Server { * \param host Host al cual transmitir. * \param port Puerto al cual transmitir. */ - Transmitter(std::string& _host, Connection::Port& _port); + Transmitter(const std::string& _host, + const Connection::Port& _port) throw(sockerr); /** * Envia datos. diff --git a/Server/src/command.cpp b/Server/src/command.cpp index 5087d9e..517d352 100644 --- a/Server/src/command.cpp +++ b/Server/src/command.cpp @@ -28,6 +28,7 @@ #include "plaqui/server/command.h" #include "plaqui/server/string.h" #include +//#include #ifdef DEBUG # include #endif // DEBUG @@ -40,13 +41,15 @@ namespace Server { Command::~Command(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } Command::Command(const string& _target, const string& _command) { #ifdef DEBUG - cerr << __FILE__ << ": target = " << target << " | " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": target = " << target << " | " << "command = " << command << endl; #endif // DEBUG set_target(_target); @@ -62,7 +65,8 @@ void Command::build(void) { } } #ifdef DEBUG - cerr << __FILE__ << ": build() = " << uri << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": build() = " << uri << endl; #endif // DEBUG } @@ -100,16 +104,18 @@ void Command::add_arg(const std::string& arg) { void Command::add_arg(const unsigned& arg) { #ifdef DEBUG - cerr << __FILE__ << ": add_arg(arg = " << arg << ") = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": add_arg(arg = " << arg << ") = " << String().from(arg) << endl; #endif // DEBUG args.push_back(String().from(arg)); build(); } -istream& operator>>(istream& is, Command& command) { +istream& operator>>(istream& is, Command& command) throw(HTTPError, sockerr) { #ifdef DEBUG - cerr << __FILE__ << ": operator>>()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator>>()" << endl; #endif // DEBUG // Obtengo datos del Request HTTP. is >> static_cast(command); @@ -133,9 +139,10 @@ istream& operator>>(istream& is, Command& command) { return is; } -ostream& operator<<(ostream& os, const Command& command) { +ostream& operator<<(ostream& os, const Command& command) throw (sockerr) { #ifdef DEBUG - cerr << __FILE__ << ": operator<<()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator<<()" << endl; #endif // DEBUG // Manda el request HTTP con la URI que representa el comando. os << static_cast(command); diff --git a/Server/src/connection.cpp b/Server/src/connection.cpp index a8f17ea..75915c9 100644 --- a/Server/src/connection.cpp +++ b/Server/src/connection.cpp @@ -39,14 +39,16 @@ namespace Server { Connection::~Connection(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } Connection::Connection(const sockbuf::sockdesc& sd): socket(sd) { #ifdef DEBUG - cerr << __FILE__ << ": sd = " << sd.sock; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": sd = " << sd.sock; #endif // DEBUG host = socket->peerhost(); port = socket->peerport(); @@ -58,7 +60,8 @@ Connection::Connection(const sockbuf::sockdesc& sd): Connection::Connection(const sockbuf::type& type, const std::string& host, const Port& port): socket(type), host(host), port(port) { #ifdef DEBUG - cerr << __FILE__ << ": type = " << type << " | host = " << host + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": type = " << type << " | host = " << host << " | port = " << port << endl; #endif // DEBUG } @@ -66,13 +69,22 @@ Connection::Connection(const sockbuf::type& type, const std::string& host, Connection::Connection(const std::string& host, const Port& port): host(host), port(port) { #ifdef DEBUG - cerr << __FILE__ << ": host = " << host << " | port = " << port << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": host = " << host << " | port = " << port << endl; #endif // DEBUG } void Connection::finish(bool attach) { +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": finish(attach = " << attach << ")." << endl; +#endif // DEBUG //socket_mutex.lock(); - socket->shutdown(sockbuf::shut_readwrite); + try { + socket->shutdown(sockbuf::shut_readwrite); + } catch (const sockerr& e) { + error(e.serrno(), e.errstr()); + } //socket_mutex.unlock(); Runnable::finish(attach); } diff --git a/Server/src/controlclient.cpp b/Server/src/controlclient.cpp index 48ef328..15b576e 100644 --- a/Server/src/controlclient.cpp +++ b/Server/src/controlclient.cpp @@ -39,34 +39,37 @@ namespace Server { ControlClient::~ControlClient(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG // TODO Temporal: espero que el receiver muera. receiver.finish(true); } -ControlClient::ControlClient(const string& host, const Connection::Port& port): - Connection(sockbuf::sock_stream, host, port) { +ControlClient::ControlClient(const string& _host, + const Connection::Port& _port) throw(sockerr): + Connection(sockbuf::sock_stream, _host, _port) { #ifdef DEBUG - cerr << __FILE__ << ": host = " << host + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": host = " << host << " | port = " << port << endl; #endif // DEBUG + socket->connect(host.c_str(), port); + host = socket->localhost(); + port = socket->localport(); } void ControlClient::real_run(void) { #ifdef DEBUG - cerr << __FILE__ << ": real_run." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run." << endl; #endif // DEBUG try { - socket->connect(host.c_str(), port); } catch (const sockerr& e) { - // Poner una señal de error específica? - error_received(1); - finish(); + // TODO Poner una señal de error específica? + error(e.serrno(), e.errstr()); return; } - host = socket->localhost(); - port = socket->localport(); // TODO sacar signal_connected? connected(); // TODO Temporal: el receiver empieza a escuchar. @@ -78,14 +81,19 @@ void ControlClient::real_run(void) { socket >> response; // Si se cerró el socket. } catch (const ios::failure& e) { - stop = true; - continue; + // TODO poner buenos codigos de error. + error(1000000, "Se desconectó."); + return; + } catch (const sockerr& e) { + error(e.serrno(), e.errstr()); + return; // Si hay un error al parsear la respuesta. } catch (const HTTPResponse::Error& e) { #ifdef DEBUG - cerr << __FILE__ << " : real_run() ERROR nro: " << e << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << " : real_run() ERROR nro: " << e << endl; #endif // DEBUG - // TODO - pasar como parametro codigo de error o algo. + // TODO - es un error recuperable? O manda señal error()? error_received(e); continue; } @@ -101,9 +109,15 @@ void ControlClient::real_run(void) { } void ControlClient::send(const Command& command) { - socket << command << flush; + try { + socket << command << flush; + } catch (const sockerr& e) { + error(e.serrno(), e.errstr()); + finish(); + } #ifdef DEBUG - cerr << __FILE__ << ": send() Enviado!" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": send() Enviado!" << endl; #endif // DEBUG } @@ -121,6 +135,9 @@ ControlClient::SignalErrorReceived& ControlClient::signal_error_received(void) { // TODO - temporal Receiver::SignalFrameReceived& ControlClient::signal_frame_received(void) { + // XXX - cuidado, esto puede dar quilombo si no esta protegido por un mutex, + // aunque no deberia porque la señal no es llamada hasta que no se empice + // la transmision y la señal se conecta antes de pedir la transmision. return receiver.signal_frame_received(); } diff --git a/Server/src/controlserver.cpp b/Server/src/controlserver.cpp index 23f89c4..a9cf729 100644 --- a/Server/src/controlserver.cpp +++ b/Server/src/controlserver.cpp @@ -44,20 +44,23 @@ namespace Server { ControlServer::~ControlServer(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } ControlServer::ControlServer(const sockbuf::sockdesc& sd): Connection(sd) { #ifdef DEBUG - cerr << __FILE__ << ": sd = " << sd.sock << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": sd = " << sd.sock << endl; #endif // DEBUG } void ControlServer::real_run(void) { #ifdef DEBUG - cerr << __FILE__ << ": real_run()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run()" << endl; #endif // DEBUG //char buf[BUFSIZ]; while (!stop) { @@ -65,15 +68,23 @@ void ControlServer::real_run(void) { try { //Glib::Mutex::Lock lock(socket_mutex); socket >> command; - // Si se cerró el socket. } catch (const ios::failure& e) { - stop = true; - continue; + // TODO poner buenos codigos de error. + error(1000000, "Se desconectó."); + return; + } catch (const sockerr& e) { + error(e.serrno(), e.errstr()); + return; + // Si se cerró el socket. + //} catch (const ios::failure& e) { + // stop = true; + // continue; // Si hay un error al parsear el comando, se envia una respuesta con el // error. } catch (const HTTPError& e) { #ifdef DEBUG - cerr << __FILE__ << " : real_run() ERROR: status_code = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << " : real_run() ERROR: status_code = " << e.code << " | reason = " << HTTPMessage::reason(e.code) << " | desc = " << e.what() << endl; #endif // DEBUG @@ -89,7 +100,8 @@ void ControlServer::real_run(void) { bool is_first = true; while (!stop && socket.getline(buf, BUFSIZ)) { #ifdef DEBUG - cerr << __FILE__ << " Recibiendo inea: " << buf << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << " Recibiendo inea: " << buf << endl; #endif // DEBUG int len = strlen(buf); // Si tiene un retorno de carro, lo elimina. @@ -119,7 +131,8 @@ void ControlServer::real_run(void) { } */ #ifdef DEBUG - cerr << __FILE__ << " : real_run() Despachando comando: target = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << " : real_run() Despachando comando: target = " << command.get_target() << " | command = " << command.get_command() << " | args = [" << String::join(command.get_args(), ", ") << "]" << endl; @@ -133,7 +146,8 @@ void ControlServer::send(const HTTPResponse& response) { //Glib::Mutex::Lock lock(socket_mutex); socket << response << flush; #ifdef DEBUG - cerr << __FILE__ << ": send() Enviado!" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": send() Enviado!" << endl; #endif // DEBUG } diff --git a/Server/src/httperror.cpp b/Server/src/httperror.cpp index b00ded5..b833ad1 100644 --- a/Server/src/httperror.cpp +++ b/Server/src/httperror.cpp @@ -38,14 +38,16 @@ namespace Server { HTTPError::~HTTPError(void) throw() { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } HTTPError::HTTPError(unsigned code, const std::string& desc) throw(): runtime_error(desc), code(code) { #ifdef DEBUG - cerr << __FILE__ << ": code = " << code << " | desc = " << desc << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": code = " << code << " | desc = " << desc << endl; #endif // DEBUG } diff --git a/Server/src/httpheaders.cpp b/Server/src/httpheaders.cpp index 04bd6c8..b54201e 100644 --- a/Server/src/httpheaders.cpp +++ b/Server/src/httpheaders.cpp @@ -25,8 +25,9 @@ // $Id$ // -#include "plaqui/server/httpheaders.h" #include "plaqui/server/httperror.h" +#include "plaqui/server/httpmessage.h" +#include "plaqui/server/httpheaders.h" #include "plaqui/server/string.h" //#include #ifdef DEBUG @@ -41,33 +42,41 @@ namespace Server { HTTPHeaders::~HTTPHeaders(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } -istream& operator>>(istream& is, HTTPHeaders& h) throw(HTTPError) { +istream& operator>>(istream& is, HTTPHeaders& h) + throw(HTTPError, sockerr, ios::failure) { #ifdef DEBUG - cerr << __FILE__ << ": operator>>()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator>>()" << endl; #endif // DEBUG char buf[BUFSIZ]; - is.getline(buf, BUFSIZ); + // Fin del stream, no había cabeceras. + if (!is.getline(buf, BUFSIZ)) { + throw ios::failure("eof"); + } string sbuf = buf; string::size_type pos = sbuf.find(":"); if (pos == string::npos) { // FIXME poner mejores excepciones. - throw HTTPError(400, sbuf + ": No es una cabecera válida."); + throw HTTPError(HTTPMessage::BAD_REQUEST, sbuf + ": No es una cabecera válida."); } h[sbuf.substr(0, pos)] = String(sbuf.substr(pos + 1)).trim(); #ifdef DEBUG - cerr << __FILE__ << " " << sbuf.substr(0, pos) << " = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << " " << sbuf.substr(0, pos) << " = " << h[sbuf.substr(0, pos)] << endl; #endif // DEBUG return is; } -ostream& operator<<(ostream& os, const HTTPHeaders& h) { +ostream& operator<<(ostream& os, const HTTPHeaders& h) throw(sockerr) { #ifdef DEBUG - cerr << __FILE__ << ": operator<<()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator<<()" << endl; #endif // DEBUG for (HTTPHeaders::const_iterator i = h.begin(); i != h.end(); ++i) { diff --git a/Server/src/httpmessage.cpp b/Server/src/httpmessage.cpp index c97da08..260fe80 100644 --- a/Server/src/httpmessage.cpp +++ b/Server/src/httpmessage.cpp @@ -41,14 +41,16 @@ namespace Server { HTTPMessage::~HTTPMessage(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } HTTPMessage::HTTPMessage(const string& _body, const string& _version): version(_version) { #ifdef DEBUG - cerr << __FILE__ << ": version = " << version << " | body (" + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": version = " << version << " | body (" << _body.length() << ") = " << _body << endl; #endif // DEBUG headers["Accept-Ranges"] = "bytes"; @@ -66,7 +68,8 @@ const string& HTTPMessage::get_body(void) const { istream& operator>>(istream& is, HTTPMessage& m) { #ifdef DEBUG - cerr << __FILE__ << ": operator>>()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator>>()" << endl; #endif // DEBUG char buf[BUFSIZ]; while (is.getline(buf, BUFSIZ)) { @@ -97,7 +100,8 @@ istream& operator>>(istream& is, HTTPMessage& m) { ostream& operator<<(ostream& os, const HTTPMessage& m) { #ifdef DEBUG - cerr << __FILE__ << ": operator<<()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator<<()" << endl; #endif // DEBUG return os << m.headers << "\r\n" // Fin de cabeceras << m.body; diff --git a/Server/src/httprequest.cpp b/Server/src/httprequest.cpp index d62b785..1da38a7 100644 --- a/Server/src/httprequest.cpp +++ b/Server/src/httprequest.cpp @@ -39,7 +39,8 @@ namespace Server { HTTPRequest::~HTTPRequest(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } @@ -47,7 +48,8 @@ HTTPRequest::HTTPRequest(const string& uri, const HTTPMethod& method, const string& query, const string& body, const string& version): HTTPMessage(body, version), method(method), uri(uri), query(query) { #ifdef DEBUG - cerr << __FILE__ << ": uri = " << uri << " | " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": uri = " << uri << " | " << "method = " << method_str() << " | " << "query = " << query << " | " << "body.length = " << body.length() << " | " @@ -66,18 +68,20 @@ string HTTPRequest::method_str(void) const { } istream& operator>>(istream& is, HTTPRequest& req) - throw(HTTPError, ios::failure) { + throw(HTTPError, sockerr, ios::failure) { #ifdef DEBUG - cerr << __FILE__ << ": operator>>()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator>>()" << endl; #endif // DEBUG char buf[BUFSIZ]; // Obtengo primera línea (request) if (!is.getline(buf, BUFSIZ)) { - // No hay más líneas. - throw ios::failure("socket closed"); + // Fin de archivo. + throw ios::failure("eof"); } #ifdef DEBUG - cerr << __FILE__ << ":\tRecibiendo linea: " << buf << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ":\tRecibiendo linea: " << buf << endl; #endif // DEBUG String line(buf); // Si es la primera línea, es el request. @@ -144,9 +148,10 @@ istream& operator>>(istream& is, HTTPRequest& req) return is; } -ostream& operator<<(ostream& os, const HTTPRequest& req) { +ostream& operator<<(ostream& os, const HTTPRequest& req) throw(sockerr) { #ifdef DEBUG - cerr << __FILE__ << ": operator<<()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator<<()" << endl; #endif // DEBUG os << req.method_str() << " " << req.uri; if (req.query.length()) { diff --git a/Server/src/httpresponse.cpp b/Server/src/httpresponse.cpp index 46cc55e..0177ae3 100644 --- a/Server/src/httpresponse.cpp +++ b/Server/src/httpresponse.cpp @@ -40,14 +40,16 @@ namespace Server { HTTPResponse::~HTTPResponse(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } HTTPResponse::HTTPResponse(const string& body, const string& version): HTTPMessage(body, version) { #ifdef DEBUG - cerr << __FILE__ << ": body.length = " << body.length() + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": body.length = " << body.length() << " | version = " << version << endl; #endif // DEBUG } @@ -55,34 +57,38 @@ HTTPResponse::HTTPResponse(const string& body, const string& version): HTTPResponse::HTTPResponse(const HTTPError& error): status_code(error.code) { #ifdef DEBUG - cerr << __FILE__ << ": HTTPError(status_code = " << error.code + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": HTTPError(status_code = " << error.code << ", reason = " << HTTPMessage::reason(error.code) << ", desc = " << error.what() << ")" << endl; #endif // DEBUG - set_body(string(""); + set_body(string(""); } HTTPResponse::HTTPResponse(unsigned status_code, const string& body): HTTPMessage(body), status_code(status_code) { #ifdef DEBUG - cerr << __FILE__ << ": status_code = " << status_code + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": status_code = " << status_code << " | body.length = " << body.length() << endl; #endif // DEBUG } istream& operator>>(istream& is, HTTPResponse& resp) - throw (HTTPResponse::Error, ios::failure) { + throw (HTTPResponse::Error, sockerr, ios::failure) { #ifdef DEBUG - cerr << __FILE__ << ": operator>>()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator>>()" << endl; #endif // DEBUG char buf[BUFSIZ]; // Obtengo primera línea (request) if (!is.getline(buf, BUFSIZ)) { - // No hay mas líneas. - throw ios::failure("socket closed"); + // Fin de archivo. + throw ios::failure("eof"); } #ifdef DEBUG - cerr << __FILE__ << ":\tRecibiendo linea: " << buf << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ":\tRecibiendo linea: " << buf << endl; #endif // DEBUG String line(buf); // Si es la primera línea, es el request. @@ -123,9 +129,10 @@ istream& operator>>(istream& is, HTTPResponse& resp) return is; } -ostream& operator<<(ostream& os, const HTTPResponse& resp) { +ostream& operator<<(ostream& os, const HTTPResponse& resp) throw(sockerr) { #ifdef DEBUG - cerr << __FILE__ << ": operator<<()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator<<()" << endl; #endif // DEBUG os << "HTTP/" << resp.version << " " << resp.status_code << " " << HTTPMessage::reason(resp.status_code) << "\r\n"; diff --git a/Server/src/plant.cpp b/Server/src/plant.cpp index e46e692..b01f1a5 100644 --- a/Server/src/plant.cpp +++ b/Server/src/plant.cpp @@ -29,8 +29,6 @@ #include #include #include -#include -#include #ifdef DEBUG # include #endif // DEBUG @@ -43,7 +41,8 @@ namespace Server { Plant::~Plant(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG // Termino transmisiones. Glib::Mutex::Lock lock(transmissions_mutex); @@ -55,7 +54,8 @@ Plant::~Plant(void) { Plant::Plant(const string& filename): simulator(filename), filename(filename) { #ifdef DEBUG - cerr << __FILE__ << ": constructor. filename = " << filename << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": constructor. filename = " << filename << endl; #endif // DEBUG // TODO plant /* simulator.add_pump("bomba1"); @@ -73,7 +73,8 @@ Plant::Plant(const string& filename): simulator(filename), filename(filename) { void Plant::real_run(void) { #ifdef DEBUG - cerr << __FILE__ << ": real_run." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run." << endl; #endif // DEBUG while (!stop) { simulator_mutex.lock(); @@ -90,27 +91,57 @@ void Plant::real_run(void) { } bool Plant::transmission_start(string& host, Connection::Port& port) { +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": transmission_start(host = " << host << + ", port = " << port << ")." << endl; +#endif // DEBUG Glib::Mutex::Lock lock(transmissions_mutex); for (TransmitterList::iterator i = transmissions.begin(); i != transmissions.end(); i++) { if (((*i)->get_host() == host) && ((*i)->get_port() == port)) { +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": transmission_start ERROR: ya existe." + << endl; +#endif // DEBUG return false; } } Transmitter* trans; try { trans = new Transmitter(host, port); - } catch (...) { // TODO - Hace mas selectivo el catch? - delete trans; + } catch (const sockerr& e) { // TODO - Hace mas selectivo el catch? +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": transmission_start ERROR (" << e.serrno() + << "): " << e.errstr() << endl; +#endif // DEBUG + //delete trans; return false; +// } catch (...) { // TODO - Hace mas selectivo el catch? +//#ifdef DEBUG +// cerr << __FILE__ << "(" << __LINE__ << ")" +// << ": transmission_start ERROR: desconocido." +// << endl; +//#endif // DEBUG +// //delete trans; +// return false; } transmissions.push_back(trans); trans->run(); + host = trans->get_host(); + port = trans->get_port(); return true; } bool Plant::transmission_stop(const string& host, const Connection::Port& port) { +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": transmission_stop(host = " << host << + ", port = " << port << ")." << endl; +#endif // DEBUG Glib::Mutex::Lock lock(transmissions_mutex); for (TransmitterList::iterator i = transmissions.begin(); i != transmissions.end(); i++) { @@ -123,20 +154,23 @@ bool Plant::transmission_stop(const string& host, } bool Plant::set_open(const std::string& element, bool open) { +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": set_open(element = " << element << + ", open = " << open << ")." << endl; +#endif // DEBUG Glib::Mutex::Lock lock(simulator_mutex); return simulator.set_open(element, open); } const string Plant::get_xml(void) const { +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": get_xml()." << endl; +#endif // DEBUG ostringstream oss; - try { - ifstream ifs(filename.c_str()); - ifs >> noskipws; - copy(istream_iterator(ifs), istream_iterator(), - ostream_iterator(oss)); - } catch (...) { // TODO hacerlo mas selectivo? - return ""; - } + ifstream ifs(filename.c_str()); + ifs >> oss.rdbuf(); return oss.str(); } @@ -154,8 +188,8 @@ bool Plant::transmission_exists(const string& host, } */ -//const std::string& Plant::get_name(void) const { -// return name; +//const std::string& Plant::get_filename(void) const { +// return filename; //} /// \todo FIXME esto deberia estar protegido por un mutex. diff --git a/Server/src/receiver.cpp b/Server/src/receiver.cpp index 8185727..22cc1a8 100644 --- a/Server/src/receiver.cpp +++ b/Server/src/receiver.cpp @@ -43,14 +43,16 @@ const string Receiver::FRAME_END(""); Receiver::~Receiver(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } -Receiver::Receiver(const Connection::Port& port, const string& host): - Connection(sockbuf::sock_dgram, host, port) { +Receiver::Receiver(const Connection::Port& port, const string& host) + throw(sockerr): Connection(sockbuf::sock_dgram, host, port) { #ifdef DEBUG - cerr << __FILE__ << ": port = " << port + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": port = " << port << " | host = " << host << endl; #endif // DEBUG //socket->bind(port); @@ -60,12 +62,21 @@ Receiver::Receiver(const Connection::Port& port, const string& host): // XXX EL XML DEBE EMPEZAR Y FINALIZAR EN UNA LINEA SEPARADA. void Receiver::real_run(void) { #ifdef DEBUG - cerr << __FILE__ << ": real_run." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run." << endl; #endif // DEBUG char buf[BUFSIZ]; bool in_frame = false; stringstream ss; - while (!stop && socket.getline(buf, BUFSIZ)) { + while (!stop) { + try { + if (!socket.getline(buf, BUFSIZ)) { + return; // Se terminó la transmision. + } + } catch (const sockerr& e) { + error(e.serrno(), e.errstr()); + return; + } string sbuf = buf; if (in_frame) { string::size_type pos = sbuf.find(FRAME_END); diff --git a/Server/src/runnable.cpp b/Server/src/runnable.cpp index 68296e4..c134b83 100644 --- a/Server/src/runnable.cpp +++ b/Server/src/runnable.cpp @@ -40,20 +40,23 @@ namespace Server { Runnable::~Runnable(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor(this = " << this << ")" + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor(this = " << this << ")" << endl; #endif // DEBUG } Runnable::Runnable(void): thread(0), stop(false) { #ifdef DEBUG - cerr << __FILE__ << ": constructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": constructor." << endl; #endif // DEBUG } void Runnable::static_run(Runnable* runner) { #ifdef DEBUG - cerr << __FILE__ << ": static_run(runner = " << runner << ")" + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": static_run(runner = " << runner << ")" << endl; #endif // DEBUG runner->real_run(); @@ -63,7 +66,8 @@ void Runnable::static_run(Runnable* runner) { void Runnable::run(bool detach) { #ifdef DEBUG - cerr << __FILE__ << ": run(detach = " << detach << ")" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": run(detach = " << detach << ")" << endl; #endif // DEBUG // Si vamos a correr la tarea en un thread. if (detach) { @@ -81,7 +85,8 @@ void Runnable::run(bool detach) { void Runnable::finish(bool attach) { #ifdef DEBUG - cerr << __FILE__ << ": finish(attach = " << attach << ")" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": finish(attach = " << attach << ")" << endl; #endif // DEBUG stop = true; if (attach) { @@ -93,6 +98,10 @@ Runnable::SignalFinished& Runnable::signal_finished(void) { return finished; } +Runnable::SignalError& Runnable::signal_error(void) { + return error; +} + } // namespace Server } // namespace PlaQui diff --git a/Server/src/server.cpp b/Server/src/server.cpp index 4247d91..340c2f0 100644 --- a/Server/src/server.cpp +++ b/Server/src/server.cpp @@ -29,8 +29,8 @@ #include "plaqui/server/connection.h" #include "plaqui/server/controlserver.h" #include -// FIXME - sacar sstream (a menos que se necesite) #include +#include #ifdef DEBUG # include "plaqui/server/string.h" # include @@ -44,7 +44,8 @@ namespace Server { Server::~Server(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG // Termino plantas. Glib::Mutex::Lock lock(plants_mutex); @@ -53,10 +54,11 @@ Server::~Server(void) { } } -Server::Server(const string& plant_filename, const Connection::Port& port): - TCPServer(port) { +Server::Server(const string& plant_filename, const Connection::Port& port) + throw(sockerr): TCPServer(port) { #ifdef DEBUG - cerr << __FILE__ << ": port = " << port << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": port = " << port << endl; #endif // DEBUG // FIXME Glib::Mutex::Lock lock(plants_mutex); @@ -68,10 +70,10 @@ Server::Server(const string& plant_filename, const Connection::Port& port): plants["default"]->run(); } -Connection* Server::new_connection( - const sockbuf::sockdesc& sd) { +Connection* Server::new_connection(const sockbuf::sockdesc& sd) { #ifdef DEBUG - cerr << __FILE__ << ": new_connection(sd = " << sd.sock << ")" + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": new_connection(sd = " << sd.sock << ")" << endl; #endif // DEBUG ControlServer* connection = new ControlServer(sd); @@ -84,15 +86,10 @@ Connection* Server::new_connection( return connection; } -void Server::on_plant_updated(const Plant* plant) { -#ifdef DEBUG - cerr << __FILE__ << ": on_plant_updated(plant = " << plant << ")." << endl; -#endif // DEBUG -} - void Server::on_plant_finished(const char* plant) { #ifdef DEBUG - cerr << __FILE__ << ": on_plant_finished(plant_name = " << plant << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": on_plant_finished(plant_name = " << plant << endl; #endif // DEBUG Glib::Mutex::Lock lock(plants_mutex); plants.erase(plant); @@ -102,7 +99,8 @@ void Server::on_plant_finished(const char* plant) { void Server::on_control_command_received(const Command& command, ControlServer* controlserver) { #ifdef DEBUG - cerr << __FILE__ << ": on_control_command_received(target = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": on_control_command_received(target = " << command.get_target() << ", command = " << command.get_command() << ", args = [" << String::join(command.get_args(), ", ") << "])" << endl; @@ -173,7 +171,7 @@ HTTPResponse* Server::cmd_server_status(void) const { // FIXME stringstream xml; xml << "" << endl; - xml << "\t0.9" << endl; + xml << "\t" VERSION "" << endl; xml << "\t" << endl; xml << "\t\tNicolás Dimov" << endl; xml << "\t\tLeandro Lucarella" << endl; @@ -313,6 +311,7 @@ HTTPResponse* Server::cmd_plant_get(const Command& command) { return new HTTPResponse(HTTPMessage::NOT_FOUND, string(""); } + // TODO try/catch? string xml = plants[plant]->get_xml(); if (xml.length()) { return new HTTPResponse(HTTPMessage::OK, xml); diff --git a/Server/src/tcpserver.cpp b/Server/src/tcpserver.cpp index e78e53c..ffbdead 100644 --- a/Server/src/tcpserver.cpp +++ b/Server/src/tcpserver.cpp @@ -39,7 +39,8 @@ namespace Server { TCPServer::~TCPServer(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG Glib::Mutex::Lock lock(connections_mutex); for (ConnectionList::iterator con = connections.begin(); @@ -48,9 +49,11 @@ TCPServer::~TCPServer(void) { } } -TCPServer::TCPServer(const Connection::Port& port): socket(sockbuf::sock_stream) { +TCPServer::TCPServer(const Connection::Port& port) throw(sockerr): + socket(sockbuf::sock_stream) { #ifdef DEBUG - cerr << __FILE__ << ": port = " << port << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": port = " << port << endl; #endif // DEBUG // FIXME //cerr << "recvtimeout = " << socket.recvtimeout(1) << endl; @@ -59,32 +62,36 @@ TCPServer::TCPServer(const Connection::Port& port): socket(sockbuf::sock_stream) //cerr << "sendtimeout = " << socket.sendtimeout(1) << endl; socket.bind(port); #ifdef DEBUG - cerr << __FILE__ << ": escuchando en " << socket.localhost() + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": escuchando en " << socket.localhost() << ":" << socket.localport() << "." << endl; #endif // DEBUG socket.listen(MAX_PENDING_CONNECTIONS); #ifdef DEBUG - cerr << __FILE__ << ": [despues de listen()] escuchando en " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": [despues de listen()] escuchando en " << socket.localhost() << ":" << socket.localport() << "." << endl; #endif // DEBUG } -void TCPServer::finish(bool attach) { +/*void TCPServer::finish(bool attach) { //socket_mutex.lock(); socket.shutdown(sockbuf::shut_readwrite); //socket_mutex.unlock(); Runnable::finish(attach); -} +}*/ void TCPServer::on_connection_finished(Connection* connection) { #ifdef DEBUG - cerr << __FILE__ << ": on_connection_finished(connection = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": on_connection_finished(connection = " << connection << ")" << endl; #endif // DEBUG Glib::Mutex::Lock lock(connections_mutex); connections.remove(connection); #ifdef DEBUG - cerr << __FILE__ << ": lista de conexiones" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": lista de conexiones" << endl; for (ConnectionList::const_iterator i = connections.begin(); i != connections.end(); i++) { cerr << "\t " << *i << endl; @@ -95,21 +102,29 @@ void TCPServer::on_connection_finished(Connection* connection) { /// \todo TODO: ver tema de timeout o como salir de un accept(). void TCPServer::real_run(void) { #ifdef DEBUG - cerr << __FILE__ << ": real_run()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run()" << endl; #endif // DEBUG Connection* connection; while (!stop) { // Forma grasa de salir del accept: crear conexion que salga al toque. - connection = new_connection(socket.accept()); + try { + connection = new_connection(socket.accept()); + } catch (const sockerr& e) { // No se si el accept() puede fallar. + error(e.serrno(), e.errstr()); + continue; // Supongo que puede seguir aceptando conexiones. + } #ifdef DEBUG - cerr << __FILE__ << ": real_run(): connection = " << connection + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run(): connection = " << connection << endl; #endif // DEBUG Glib::Mutex::Lock lock(connections_mutex); // XXX connections_mutex.lock(); connections.push_back(connection); #ifdef DEBUG - cerr << __FILE__ << ": real_run(): lista de conexiones" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run(): lista de conexiones" << endl; for (ConnectionList::const_iterator i = connections.begin(); i != connections.end(); i++) { cerr << "\t " << *i << endl; @@ -129,7 +144,8 @@ void TCPServer::real_run(void) { bool TCPServer::disconnect(const std::string& host, const Connection::Port& port) { #ifdef DEBUG - cerr << __FILE__ << ": disconnect(host = " << host + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": disconnect(host = " << host << ", port = " << port << ")" << endl; #endif // DEBUG Glib::Mutex::Lock lock(connections_mutex); @@ -143,9 +159,11 @@ bool TCPServer::disconnect(const std::string& host, const Connection::Port& port return false; } +/// \todo TODO Hay que reemplazarlo por una lista generica. TCPServer::ConnectionInfoList TCPServer::get_connected(void) { #ifdef DEBUG - cerr << __FILE__ << ": get_connected()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": get_connected()" << endl; #endif // DEBUG TCPServer::ConnectionInfoList cl; Glib::Mutex::Lock lock(connections_mutex); diff --git a/Server/src/transmitter.cpp b/Server/src/transmitter.cpp index de940f9..b59992e 100644 --- a/Server/src/transmitter.cpp +++ b/Server/src/transmitter.cpp @@ -41,41 +41,55 @@ namespace Server { Transmitter::~Transmitter(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } -Transmitter::Transmitter(string& _host, Connection::Port& _port): - Connection(sockbuf::sock_dgram, _host, _port) { +Transmitter::Transmitter(const string& _host, const Connection::Port& _port) + throw(sockerr): Connection(sockbuf::sock_dgram, _host, _port) { #ifdef DEBUG - cerr << __FILE__ << ": _host = " << _host + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": _host = " << _host << " | _port = " << _port << endl; #endif // DEBUG socket->connect(host.c_str(), port); - // Reasigno el host y puerto bien, tanto de este objeto como los que se - // environ para indicar su valor correcto. - host = socket->peerhost(); - port = socket->peerport(); - _host = socket->peerhost(); - _port = socket->peerport(); + // Reasigno el host y puerto bien. + host = socket->peerhost(); + port = socket->peerport(); +#ifdef DEBUG + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": (real) host = " << _host + << " | port = " << _port << endl; +#endif // DEBUG } /// \todo debría dar una excepción (?) void Transmitter::real_run(void) { #ifdef DEBUG - cerr << __FILE__ << ": real_run()." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": real_run()." << endl; #endif // DEBUG // No hace nada, porque solo actua cuando se manda algo con send(). while (!stop) { - Glib::usleep(1000); + Glib::usleep(500000); // 1/2 segundo } } void Transmitter::send(const string& data) { #ifdef DEBUG - cerr << __FILE__ << ": send(data = " << data << ")." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": send(data = " << data << ")." << endl; #endif // DEBUG - socket << data << flush; + if (stop) { + return; + } + try { + socket << data << flush; + } catch (const sockerr& e) { + error(e.serrno(), e.errstr()); + stop = true; + } } } // namespace Server diff --git a/Server/tests/Makefile.am b/Server/tests/Makefile.am index 025269f..60b952f 100644 --- a/Server/tests/Makefile.am +++ b/Server/tests/Makefile.am @@ -46,7 +46,7 @@ server_test_LDADD = \ @PACKAGE_LIBS@ \ -lsocket++ \ ../src/libplaquiserver.a \ - ../../Model/src/model.a + ../../Model/src/libplaquimodel.a client_test_LDADD = \ @PACKAGE_LIBS@ \ diff --git a/Server/tests/client_test.cpp b/Server/tests/client_test.cpp index 88027e1..9ff2fbb 100644 --- a/Server/tests/client_test.cpp +++ b/Server/tests/client_test.cpp @@ -36,6 +36,14 @@ using namespace PlaQui::Server; ControlClient* client = NULL; +void on_error(const Runnable::Error& code, const string& desc) { + cerr << "--------------------------------------------------------" << endl; + cerr << "Error en el cliente:" << endl; + cerr << "Código: " << code << endl; + cerr << "Descripción: " << desc << endl; + cerr << "--------------------------------------------------------" << endl; +} + void on_finished(void) { client = NULL; } @@ -87,6 +95,7 @@ int main(int argc, char* argv[]) { try { // Corre el cliente. client = new ControlClient(host, port); + client->signal_error().connect(SigC::slot(on_error)); client->signal_finished().connect(SigC::slot(on_finished)); client->signal_connected().connect(SigC::slot(on_connected)); client->signal_ok_received().connect(SigC::slot(on_ok_received)); diff --git a/Server/tests/server_test.cpp b/Server/tests/server_test.cpp index bdb6190..25d01a6 100644 --- a/Server/tests/server_test.cpp +++ b/Server/tests/server_test.cpp @@ -35,6 +35,14 @@ using namespace std; using namespace PlaQui::Server; +void on_error(const Runnable::Error& code, const string& desc) { + cerr << "--------------------------------------------------------" << endl; + cerr << "Error en el servidor:" << endl; + cerr << "Código: " << code << endl; + cerr << "Descripción: " << desc << endl; + cerr << "--------------------------------------------------------" << endl; +} + int main(int argc, char* argv[]) { // Termina con mas informacion si hay una excepcion no manejada. @@ -60,10 +68,10 @@ int main(int argc, char* argv[]) { // Inicializa threads. Glib::thread_init(); + Server* server = NULL; try { - // Corre el server. - Server server(filename, port); - server.run(false); + // Crea el server (empieza a escuchar). + server = new Server(filename, port); } catch (const sockerr& e) { cerr << "Socket Error: " << e.operation() << " | serrno = " << e.serrno() << " | errstr = " << e.errstr() << endl; @@ -82,13 +90,26 @@ int main(int argc, char* argv[]) { } else if (e.benign()) { cerr << "Es: recoverable read/write error like EINTR etc." << endl; } + return e.serrno(); } catch (const exception& e) { cerr << "Error: " << e.what() << endl; + return 1; } catch (const char* e) { cerr << "Error: " << e << endl; + return 2; } catch (...) { cerr << "Error desconocido!" << endl; + return 3; } + // Conecto señal para atender errores. + server->signal_error().connect(SigC::slot(on_error)); + + // Corre el server. + server->run(false); + + // Como no detachee el server, lo tengo que eliminar a mano. + delete server; + return 0; } -- 2.43.0