]> git.llucax.com Git - z.facultad/75.42/plaqui.git/commitdiff
- Ya anda el Receiver (falta meterlo en el ControlClient).
authorLeandro Lucarella <llucax@gmail.com>
Tue, 18 Nov 2003 05:01:58 +0000 (05:01 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Tue, 18 Nov 2003 05:01:58 +0000 (05:01 +0000)
- Se agrega un ejemplo de Receiver.

Server/TODO
Server/include/plaqui/server/httpmessage.h
Server/include/plaqui/server/receiver.h
Server/src/receiver.cpp
Server/tests/Makefile
Server/tests/client_test.cpp
Server/tests/receiver_test.cpp [new file with mode: 0644]

index 5bc5734ff2c5bbedfbab708a6eb927f0598aeaaf..53a61bb06e507b45a593f263e9b3aa10bd1c3012 100644 (file)
@@ -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.
index 5897d148c07096e009874c4a7bd327b68deec159..30bc794de5dd336709934409ce984f5df2826dd6 100644 (file)
@@ -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;
index 5b8c6351059ae0eb602a93fbe2c96475e0d094c8..1ac45efc3ad6f8dc7d588a2052a3460db66877e3 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "plaqui/server/connection.h"
 #include <socket++/sockinet.h>
+#include <sigc++/signal.h>
 #include <string>
 
 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<void, const std::string&> 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);
 
        };
 
index c381c7d6d104683c32e745d43bde76280099281e..8185727b8efd1c6da896df2054fd3dfbf348bf41 100644 (file)
@@ -26,6 +26,7 @@
 //
 
 #include "plaqui/server/receiver.h"
+#include <sstream>
 #ifdef DEBUG
 #      include <iostream>
 #endif // DEBUG
@@ -36,35 +37,61 @@ namespace PlaQui {
 
 namespace Server {
 
+const string Receiver::FRAME_BEGIN("<plantstatus");
+
+const string Receiver::FRAME_END("</plantstatus>");
+
 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 </plantstatus>.
+                               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
index 351525fdbbb86bee73499a29ae554de2f5a77fec..0885bca34b06f67a0631f6fe05fd9510a6ff5f7a 100644 (file)
@@ -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
index 02eb99190ddc6cdc9a0bd1538b2484f1e8f3a3d5..0ab975bac78fc414ec93298ae1cb679c6c4fbd18 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "plaqui/server/controlclient.h"
 #include "plaqui/server/string.h"
-//#include <socket++/sockinet.h>
 #include <iostream>
 #include <sstream>
 #include <exception>
@@ -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 (file)
index 0000000..6bb5f57
--- /dev/null
@@ -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 <llucare@fi.uba.ar>
+//----------------------------------------------------------------------------
+//
+// $Id$
+//
+
+#include "plaqui/server/receiver.h"
+#include <iostream>
+#include <sstream>
+#include <exception>
+
+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;
+}