From: Leandro Lucarella Date: Tue, 18 Nov 2003 05:01:58 +0000 (+0000) Subject: - Ya anda el Receiver (falta meterlo en el ControlClient). X-Git-Tag: svn_import~267 X-Git-Url: https://git.llucax.com/z.facultad/75.42/plaqui.git/commitdiff_plain/e90831f68ec3af87bddba19b44be388eb2b3752e - Ya anda el Receiver (falta meterlo en el ControlClient). - Se agrega un ejemplo de Receiver. --- diff --git a/Server/TODO b/Server/TODO index 5bc5734..53a61bb 100644 --- a/Server/TODO +++ b/Server/TODO @@ -4,3 +4,5 @@ $Id$ finalizar el request o no. - Hacer un try/catch en cada llamada al socket por si se desconecto, para que no muera con un segmentation fault. +- Terminal Response para que lleguen bien todos los comandos al cliente. +- Ver si sirve Runnable::signal_error y usar si sirve. diff --git a/Server/include/plaqui/server/httpmessage.h b/Server/include/plaqui/server/httpmessage.h index 5897d14..30bc794 100644 --- a/Server/include/plaqui/server/httpmessage.h +++ b/Server/include/plaqui/server/httpmessage.h @@ -59,9 +59,7 @@ namespace Server { /// Cuerpo del mensaje. std::string body; - protected: // TODO hacer privados con get() y set() ??? - - public: + public: // TODO hacer privados con get() y set() ??? /// Version HTTP. std::string version; diff --git a/Server/include/plaqui/server/receiver.h b/Server/include/plaqui/server/receiver.h index 5b8c635..1ac45ef 100644 --- a/Server/include/plaqui/server/receiver.h +++ b/Server/include/plaqui/server/receiver.h @@ -30,6 +30,7 @@ #include "plaqui/server/connection.h" #include +#include #include namespace PlaQui { @@ -39,6 +40,35 @@ namespace Server { /// Conexión para recibir el estado de una planta. class Receiver: public Connection { + // Constantes. + + private: + + /// Marca de comienzo de frame. + static const std::string FRAME_BEGIN; + + /// Marca de fin de frame. + static const std::string FRAME_END; + + + // Tipos. + + public: + + /// Tipo de señal para indicar que se recibió un cuadro. + typedef SigC::Signal1 SignalFrameReceived; + + + // Atributos. + + private: + + /// Señal que indica que se recibió un cuadro. + SignalFrameReceived frame_received; + + + // Métodos. + private: /** @@ -59,7 +89,13 @@ namespace Server { * \param port Puerto por el cual recibir estado de la planta. * \param host Host del cual recibir el estado de la planta. */ - Receiver(int port = 7528, std::string host = "localhost"); + Receiver(const Connection::Port& port = 7528, + const std::string& host = "localhost"); + + /** + * Obtiene la señal que avisa cuando se recibió un cuadro. + */ + SignalFrameReceived& signal_frame_received(void); }; diff --git a/Server/src/receiver.cpp b/Server/src/receiver.cpp index c381c7d..8185727 100644 --- a/Server/src/receiver.cpp +++ b/Server/src/receiver.cpp @@ -26,6 +26,7 @@ // #include "plaqui/server/receiver.h" +#include #ifdef DEBUG # include #endif // DEBUG @@ -36,35 +37,61 @@ namespace PlaQui { namespace Server { +const string Receiver::FRAME_BEGIN(""); + Receiver::~Receiver(void) { #ifdef DEBUG cerr << __FILE__ << ": destructor." << endl; #endif // DEBUG } -Receiver::Receiver(int port, string host): Connection(sockbuf::sock_dgram) { +Receiver::Receiver(const Connection::Port& port, const string& host): + Connection(sockbuf::sock_dgram, host, port) { #ifdef DEBUG cerr << __FILE__ << ": port = " << port << " | host = " << host << endl; #endif // DEBUG - // FIXME - deberia ir en run(). - socket->bind(port); + //socket->bind(port); + socket->bind(host.c_str(), port); } +// XXX EL XML DEBE EMPEZAR Y FINALIZAR EN UNA LINEA SEPARADA. void Receiver::real_run(void) { #ifdef DEBUG cerr << __FILE__ << ": real_run." << endl; #endif // DEBUG - // FIXME - debería tirar una excepción? - if (!socket->is_open()) { - cerr << "No se pudo conectar a " << socket->peerhost() << - ":" << socket->peerport() << "." << endl; - } else { - cerr << "Conectado a " << socket->peerhost() << - ":" << socket->peerport() << "." << endl; + char buf[BUFSIZ]; + bool in_frame = false; + stringstream ss; + while (!stop && socket.getline(buf, BUFSIZ)) { + string sbuf = buf; + if (in_frame) { + string::size_type pos = sbuf.find(FRAME_END); + if (pos == string::npos) { // No encuentra el fin + ss << sbuf << endl; + } else { // Encuentra el fin. + // Agrego al mensaje actual hasta el final . + ss << sbuf.substr(0, pos + FRAME_END.length()); + frame_received(ss.str()); + ss.str(""); + in_frame = false; + } + } else { // No esta en un frame. + string::size_type pos = sbuf.find(FRAME_BEGIN); + if (pos != string::npos) { // Encuentra el inicio + ss << sbuf.substr(pos) << endl; + in_frame = true; + } + } } } +Receiver::SignalFrameReceived& Receiver::signal_frame_received(void) { + return frame_received; +} + } // namespace Server } // namespace PlaQui diff --git a/Server/tests/Makefile b/Server/tests/Makefile index 351525f..0885bca 100644 --- a/Server/tests/Makefile +++ b/Server/tests/Makefile @@ -45,7 +45,7 @@ CXXFLAGS+=-g -DDEBUG LDFLAGS=-lsocket++ `pkg-config --libs glibmm-2.0 gthread-2.0` \ `xml2-config --libs` #-L$(LIB_FILES) -TARGETS=server_test client_test +TARGETS=server_test client_test receiver_test # Regla por defecto. all: $(TARGETS) @@ -56,9 +56,8 @@ $(LIB_FILES)/server.a: # Tests server_test: $(LIB_FILES)/server.a $(MODEL_DIR)/src/model.a server_test.o - -# Tests client_test: $(LIB_FILES)/server.a client_test.o +receiver_test: $(LIB_FILES)/server.a receiver_test.o clean: rm -f $(TARGETS) *.o diff --git a/Server/tests/client_test.cpp b/Server/tests/client_test.cpp index 02eb991..0ab975b 100644 --- a/Server/tests/client_test.cpp +++ b/Server/tests/client_test.cpp @@ -27,7 +27,6 @@ #include "plaqui/server/controlclient.h" #include "plaqui/server/string.h" -//#include #include #include #include @@ -72,7 +71,7 @@ int main(int argc, char* argv[]) { // Obtengo host. host = argv[1]; } - unsigned port = 7522; + Connection::Port port = 7522; if (argc > 2) { // Obtengo puerto. stringstream str(argv[2]); diff --git a/Server/tests/receiver_test.cpp b/Server/tests/receiver_test.cpp new file mode 100644 index 0000000..6bb5f57 --- /dev/null +++ b/Server/tests/receiver_test.cpp @@ -0,0 +1,98 @@ +// vim: set noexpandtab tabstop=4 shiftwidth=4: +//---------------------------------------------------------------------------- +// PlaQui +//---------------------------------------------------------------------------- +// This file is part of PlaQui. +// +// PlaQui is free software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// PlaQui 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 General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along +// with PlaQui; if not, write to the Free Software Foundation, Inc., 59 Temple +// Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------------- +// Creado: jue nov 13 00:53:38 ART 2003 +// Autores: Leandro Lucarella +//---------------------------------------------------------------------------- +// +// $Id$ +// + +#include "plaqui/server/receiver.h" +#include +#include +#include + +using namespace std; +using namespace PlaQui::Server; + +void on_frame_received(const string& frame) { + cout << " Frame recibido! :-D" << endl; + cout << frame << endl; +} + +int main(int argc, char* argv[]) { + + // Termina con mas informacion si hay una excepcion no manejada. + set_terminate (__gnu_cxx::__verbose_terminate_handler); + + // Mensaje de bienvenida. + cout << "Receiver test. Modo de uso: " << endl; + cout << "\t" << argv[0] << " [port] [host]" << endl; + + // Parámetros. + Connection::Port port = 7528; + if (argc > 1) { + // Obtengo puerto. + stringstream str(argv[1]); + str >> port; + } + string host = "localhost"; + if (argc > 2) { + // Obtengo host. + host = argv[2]; + } + + // Inicializa threads. + Glib::thread_init(); + + try { + // Corre el cliente. + Receiver receptor(port, host); + receptor.signal_frame_received().connect(SigC::slot(on_frame_received)); + receptor.run(false); + } catch (const sockerr& e) { + cerr << "Socket Error: " << e.operation() << " | serrno = " + << e.serrno() << " | errstr = " << e.errstr() << endl; + if (e.io()) { + cerr << "Es: non-blocking and interrupt io recoverable error." + << endl; + } else if (e.arg()) { + cerr << "Es: incorrect argument supplied. recoverable error." + << endl; + } else if (e.op()) { + cerr << "Es: operational error. recovery difficult." << endl; + } else if (e.conn()) { + cerr << "Es: connection error." << endl; + } else if (e.addr()) { + cerr << "Es: address error." << endl; + } else if (e.benign()) { + cerr << "Es: recoverable read/write error like EINTR etc." << endl; + } + } catch (const exception& e) { + cerr << "Error: " << e.what() << endl; + } catch (const char* e) { + cerr << "Error: " << e << endl; + } catch (...) { + cerr << "Error desconocido!" << endl; + } + + return 0; +}