]> git.llucax.com Git - z.facultad/75.42/plaqui.git/commitdiff
- Muchas pequeñas correcciones.
authorLeandro Lucarella <llucax@gmail.com>
Sun, 19 Oct 2003 05:23:25 +0000 (05:23 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 19 Oct 2003 05:23:25 +0000 (05:23 +0000)
- Algunos grandes cambios:
  - Se agrega soporte de threads a Runneable.
  - Estan funcionando Server y ControlServer de forma básica. Server puede
    atender peticiones y cuando se conecta alguien crea un nuevo ControlServer
    que maneja la conexión (falta liberar memoria, porque por ahora solo se
    puede salir con Ctr-C). ControlServer recibe línea por línea hasta que una
    línea sea vacía (detección simple de cabeceras HTTP).
- Se agrega un test del servidor: server_test.cpp.
- El diagrama de clases queda un poco desactualizado (y tal vez deprecated,
  debería pasarlo a Dia así queda todo con el mismo formato).

16 files changed:
Server/src/Makefile
Server/src/connection.cpp
Server/src/connection.h
Server/src/controlclient.cpp
Server/src/controlclient.h
Server/src/controlserver.cpp
Server/src/controlserver.h
Server/src/receiver.cpp
Server/src/receiver.h
Server/src/runnable.cpp [new file with mode: 0644]
Server/src/runnable.h
Server/src/server.cpp
Server/src/server.h
Server/src/server_test.cpp [new file with mode: 0644]
Server/src/transmitter.cpp
Server/src/transmitter.h

index 146f7a87f477b2bb1ecdfe6eeba0e1c52fe11c8d..861231cda42527d887020caea225f85dc21b4518 100644 (file)
 #
 
 # Opciones para el compilador.
 #
 
 # Opciones para el compilador.
-CXXFLAGS=-ansi -pedantic -Wall -g
-LDFLAGS=-lsocket++
+CXXFLAGS=-ansi -pedantic -Wall `pkg-config --cflags glibmm-2.0` `pkg-config --cflags gthread-2.0`
+CXXFLAGS+=-g -DDEBUG
+#CXXFLAGS+=-g
+#CXXFLAGS+=-O3
+LDFLAGS=-lsocket++ `pkg-config --libs glibmm-2.0` `pkg-config --libs gthread-2.0`
 
 TARGETS=connection.o controlclient.o controlserver.o receiver.o transmitter.o \
        server.o
 
 
 TARGETS=connection.o controlclient.o controlserver.o receiver.o transmitter.o \
        server.o
 
+TESTS=server_test
+
 # Regla por defecto.
 # Regla por defecto.
-all: $(TARGETS)
+all: $(TARGETS) $(TESTS)
 
 runnable_h=runnable.h
 
 runnable_h=runnable.h
+objects+=runnable.o
+runnable.o: $(runnable_h) runnable.cpp
 
 connection_h=$(runnable_h) connection.h
 
 connection_h=$(runnable_h) connection.h
-connection.o: $(connection_h)
+objects+=connection.o
+connection.o: $(connection_h) connection.cpp
 
 controlclient_h=$(connection_h) controlclient.h
 
 controlclient_h=$(connection_h) controlclient.h
-controlclient.o: $(controlclient_h)
+objects+=controlclient.o
+controlclient.o: $(controlclient_h) controlclient.cpp
 
 controlserver_h=$(connection_h) controlserver.h
 
 controlserver_h=$(connection_h) controlserver.h
-controlserver.o: $(controlserver_h)
+objects+=controlserver.o
+controlserver.o: $(controlserver_h) controlserver.cpp
 
 receiver_h=$(connection_h) receiver.h
 
 receiver_h=$(connection_h) receiver.h
-receiver.o: $(receiver_h)
+objects+=receiver.o
+receiver.o: $(receiver_h) receiver.cpp
 
 transmitter_h=$(connection_h) transmitter.h
 
 transmitter_h=$(connection_h) transmitter.h
-transmitter.o: $(transmitter_h)
+objects+=transmitter.o
+transmitter.o: $(transmitter_h) transmitter.cpp
+
+server_h=$(controlserver_h) $(transmitter_h) server.h
+objects+=server.o
+server.o: $(server_h) server.cpp
+
+# Tests
+server_test: $(objects) server_test.cpp
 
 clean:
 
 clean:
-       rm -f $(TARGETS) *.o
+       rm -f $(TARGETS) $(TESTS) *.o
index 086548a289a2114005ec213c7d77caff9d2823f9..6d48727c4f924ecc3e691a1ac645c4476a2272df 100644 (file)
 
 using namespace Plaqui;
 
 
 using namespace Plaqui;
 
+Connection::Connection(const sockbuf::sockdesc& sd):
+               socket(sd) {
+#ifdef DEBUG
+       std::cerr << __FILE__ << ": sd = " << sd.sock << std::endl;
+#endif // DEBUG
+}
+
+/*
 Connection::Connection(const sockinetbuf& sb):
                socket(sb) {
 }
 Connection::Connection(const sockinetbuf& sb):
                socket(sb) {
 }
+*/
 
 Connection::Connection(sockbuf::type type):
                socket(type) {
 
 Connection::Connection(sockbuf::type type):
                socket(type) {
index 306e273dd3b837b4ff2e318dd0d10f007d2e9250..df4cf2c7acc01df9a05615d2822ce676fc3156d4 100644 (file)
@@ -38,6 +38,9 @@ namespace Plaqui {
 
                protected:
 
 
                protected:
 
+                       /// Tamaño del buffer usado para enviar y recibir datos.
+                       static const int BUFFER_SIZE = 4096;
+
                        /// Socket a usar en la conexión.
                        iosockinet socket;
 
                        /// Socket a usar en la conexión.
                        iosockinet socket;
 
@@ -48,12 +51,19 @@ namespace Plaqui {
                         */
                        virtual ~Connection(void) {}
 
                         */
                        virtual ~Connection(void) {}
 
+                       /**
+                        * Constructor.
+                        *
+                        * \param socket Descriptor de socket a usar en la conexión.
+                        */
+                       Connection(const sockbuf::sockdesc& sd);
+
                        /**
                         * Constructor.
                         *
                         * \param socket Socket a usar en la conexión.
                         */
                        /**
                         * Constructor.
                         *
                         * \param socket Socket a usar en la conexión.
                         */
-                       Connection(const sockinetbuf& sb);
+                       //Connection(const sockinetbuf& sb);
 
                        /**
                         * Constructor.
 
                        /**
                         * Constructor.
index 3ad35f84920992f5fd45e68d2adbdd33766ac6ce..3ad70b6657f09ca49ea4125fff223e1a710f612b 100644 (file)
 //
 
 #include "controlclient.h"
 //
 
 #include "controlclient.h"
+// XXX
+#include <iostream>
 
 using namespace Plaqui;
 
 ControlClient::ControlClient(std::string host, int port):
                Connection(sockbuf::sock_stream) {
 
 using namespace Plaqui;
 
 ControlClient::ControlClient(std::string host, int port):
                Connection(sockbuf::sock_stream) {
+       // FIXME - poner en run().
        socket->connect(host.c_str(), port);
 }
 
        socket->connect(host.c_str(), port);
 }
 
+void ControlClient::real_run(void) {
+       // FIXME - debería tirar una excepción?
+       if (!socket->is_open()) {
+               std::cerr << "No se pudo conectar a " << socket->peerhost() <<
+                       ":" << socket->peerport() << "." << std::endl;
+       } else {
+               std::cerr << "Conectado a " << socket->peerhost() <<
+                       ":" << socket->peerport() << "." << std::endl;
+       }
+}
+
index ce32d865b886f5a90911583b53488d885615b7d3..adbfb5b598c941c910a502d73c03d644e3e4cab0 100644 (file)
@@ -36,6 +36,13 @@ namespace Plaqui {
        /// Conexión para enviar comandos de control a una planta.
        class ControlClient: public Connection {
 
        /// Conexión para enviar comandos de control a una planta.
        class ControlClient: public Connection {
 
+               private:
+
+                       /**
+                        * Atiende la conexión.
+                        */
+                       virtual void real_run(void);
+
                public:
 
                        /**
                public:
 
                        /**
index c9007c55dfb5ba642016735ce8adc93ce0e4b81b..4b888493b2264666c733dc3dfc7bdf8242ec18e5 100644 (file)
 //
 
 #include "controlserver.h"
 //
 
 #include "controlserver.h"
+#include <cstring>
+#include <sstream>
 
 using namespace Plaqui;
 
 
 using namespace Plaqui;
 
-//ControlServer::ControlServer(const iosockinet& socket) {
-//}
+ControlServer::ControlServer(const sockbuf::sockdesc& sd):
+               Connection(sd) {
+#ifdef DEBUG
+       std::cerr << __FILE__ << ": sd = " << sd.sock << std::endl;
+#endif // DEBUG
+}
+
+void ControlServer::real_run(void) {
+       // FIXME se tiene que ir a la clase para poder frenarlo desde afuera.
+       bool stop = false;
+       char buf[BUFFER_SIZE];
+       while (!stop) {
+               stringstream sstr;
+               while (!stop && socket.getline(buf, BUFFER_SIZE)) {
+#ifdef DEBUG
+                       std::cerr << "Reciviendo: " << buf << std::endl;
+#endif // DEBUG
+                       // Si tiene contenido, lo almaceno en el buffer de comandos.
+                       if (strlen(buf)) {
+                               sstr << buf << endl;
+                       // Si viene la línea vacía, terminan las cabeceras HTTP.
+                       } else {
+                               stop = true;
+                       }
+               }
+               // Manda mensaje a la planta.
+               //dispatch_command(parse_command(sstr.str()));
+#ifdef DEBUG
+                       std::cerr << "Recivido:" << std::endl << sstr.str() << std::endl;
+#endif // DEBUG
+               // FIXME - hacer respuesta XML.
+               socket << "Ok!" << std::endl;
+       }
+}
 
 
index c97313417e07edeebfa9070e0e81f96056e31a08..28cd032c4016f2c19802280d2e1f871045130468 100644 (file)
@@ -36,6 +36,13 @@ namespace Plaqui {
        /// Conexión para recibir comandos de control para una planta.
        class ControlServer: public Connection {
 
        /// Conexión para recibir comandos de control para una planta.
        class ControlServer: public Connection {
 
+               protected:
+
+                       /**
+                        * Atiende la conexión.
+                        */
+                       virtual void real_run(void);
+
                public:
 
                        /**
                public:
 
                        /**
@@ -46,9 +53,9 @@ namespace Plaqui {
                        /**
                         * Constructor.
                         *
                        /**
                         * Constructor.
                         *
-                        * \param socket  Socket a usar para recibir comandos.
+                        * \param sd Descriptor del socket a usar para recibir comandos.
                         */
                         */
-                       ControlServer(const sockinetbuf& socket): Connection(socket) {}
+                       ControlServer(const sockbuf::sockdesc& sd);
 
        };
 
 
        };
 
index 172a19f63e8aae99ec1b0108b4eb4bb32e9886e2..0f9f32cde3ebf476ce3e9e762cba738d9915d7b4 100644 (file)
 
 #include "receiver.h"
 
 
 #include "receiver.h"
 
-/*
-Receiver::Receiver(int port, std::string host): Connection(sockbuf::dgram) {
+using namespace Plaqui;
+
+Receiver::Receiver(int port, std::string host):
+               Connection(sockbuf::sock_dgram) {
+       // FIXME - deberia ir en run().
        socket->bind(port);
 }
        socket->bind(port);
 }
-*/
+
+void Receiver::run(void) {
+       // FIXME - debería tirar una excepción?
+       if (!socket->is_open()) {
+               std::cerr << "No se pudo conectar a " << socket->peerhost() <<
+                       ":" << socket->peerport() << "." << std::endl;
+       } else {
+               std::cerr << "Conectado a " << socket->peerhost() <<
+                       ":" << socket->peerport() << "." << std::endl;
+       }
+}
 
 
index 8be4e300c881d66882f0504e723d8fbde0016bf5..6de86341c13e3b51b9e412fa48a4b5f0422525ad 100644 (file)
@@ -50,8 +50,12 @@ namespace Plaqui {
                         * \param port Puerto por el cual recibir estado de la planta.
                         * \param host Host del cual recibir el estado de la planta.
                         */
                         * \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"*/):
-                               Connection(sockbuf::sock_dgram) { socket->bind(port); }
+                       Receiver(int port = 7528, std::string host = "localhost");
+
+                       /**
+                        * Recibe la transmisión.
+                        */
+                       virtual void run(void);
 
        };
 
 
        };
 
diff --git a/Server/src/runnable.cpp b/Server/src/runnable.cpp
new file mode 100644 (file)
index 0000000..d962980
--- /dev/null
@@ -0,0 +1,59 @@
+// 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:  dom oct 19 01:13:33 ART 2003
+// Autores: Leandro Lucarella <llucare@fi.uba.ar>
+//----------------------------------------------------------------------------
+//
+// $Id$
+//
+
+#include "runnable.h"
+#include <sigc++/class_slot.h>
+#include <glibmm/thread.h>
+#ifdef DEBUG
+#      include <iostream>
+#endif // DEBUG
+
+using namespace Plaqui;
+
+Runnable::Runnable(void): thread(0) {
+}
+
+void Runnable::run(bool detach) {
+#ifdef DEBUG
+       std::cerr << __FILE__ << ": detach = " << detach << std::endl;
+#endif // DEBUG
+       // Si vamos a correr la tarea en un thread.
+       if (detach) {
+               // Nos aseguramos de tener threads.
+               if (!Glib::thread_supported()) {
+                       Glib::thread_init();
+               }
+               // Corremos el thread.
+               thread = Glib::Thread::create(
+                               SigC::slot_class(*this, &Runnable::real_run), true);
+       // Si no corremos la tarea normalmente.
+       } else {
+               real_run();
+       }
+               
+}
+
index 04cb094fc57c58aad8d3dbfc217883a813913a86..39a221f26a684bc1569c6930a9529b42d6f92f11 100644 (file)
 #ifndef PLAQUI_RUNNABLE_H
 #define PLAQUI_RUNNABLE_H
 
 #ifndef PLAQUI_RUNNABLE_H
 #define PLAQUI_RUNNABLE_H
 
+#include <glibmm/thread.h>
+
 namespace Plaqui {
 
        /// ealizauna tarea (generalmente en un thread).
        class Runnable {
 
 namespace Plaqui {
 
        /// ealizauna tarea (generalmente en un thread).
        class Runnable {
 
+               private:
+                       // Thread en el cual correr la tarea.
+                       Glib::Thread* thread;
+
+               protected:
+
+                       /// Realiza la terea.
+                       virtual void real_run(void) = 0;
+
                public:
 
                public:
 
-                       /// Realiza la tarea.
-                       virtual void run(void) = 0;
+                       /**
+                        * Destructor.
+                        */
+                       virtual ~Runnable(void) {}
+
+                       /**
+                        * Constructor.
+                        */
+                       Runnable(void);
+
+                       /**
+                        * Comienza la tares.
+                        *
+                        * \param detach Si es true se corre en un thread propio. Si no no
+                        *                               retorna hasta que finaliza.
+                        */
+                       virtual void run(bool detach = true);
 
        };
 
 
        };
 
index bbf41c029045fd8401a98c91237713cf9c20ee8f..c0d0341bf15c08135eb3400e56b6d7db083ec2db 100644 (file)
 //
 
 #include "server.h"
 //
 
 #include "server.h"
+#ifdef DEBUG
+#      include <iostream>
+#endif // DEBUG
 
 using namespace Plaqui;
 
 Server::Server(int port):
                socket(sockbuf::sock_stream) {
 
 using namespace Plaqui;
 
 Server::Server(int port):
                socket(sockbuf::sock_stream) {
-#warning Not implemented!
-       // TODO
+       socket.bind(port);
+#ifdef DEBUG
+       std::cerr << "Escuchando en " << socket.localhost() <<
+               ":" << socket.localport() << "." << std::endl;
+#endif // DEBUG
+       socket.listen();
 }
 
 bool Server::start_transmission(std::string host, int port) {
 }
 
 bool Server::start_transmission(std::string host, int port) {
-#warning Not implemented!
        // TODO
        return false;
 }
 
 bool Server::stop_transmission(std::string host, int port) {
        // TODO
        return false;
 }
 
 bool Server::stop_transmission(std::string host, int port) {
-#warning Not implemented!
        // TODO
        return false;
 }
 
        // TODO
        return false;
 }
 
+void Server::real_run(void) {
+       // FIXME se tiene que ir a la clase para poder frenarlo desde afuera.
+       bool stop = false;
+       ControlServer* control_server;
+       while (!stop) {
+               control_server = new ControlServer(socket.accept());
+               controllers.push_back(control_server);
+               control_server->run();
+       }
+}
+
index ccd2c0e5e2a81f84895a523c4f883a30a70840da..eccbd9a7a408b8a4599cf8470a6737a4b1018406 100644 (file)
@@ -51,7 +51,7 @@ namespace Plaqui {
                        typedef std::list<Transmitter*> TransmitterList;
 
                        /// Socket para escuchar conexiones.
                        typedef std::list<Transmitter*> TransmitterList;
 
                        /// Socket para escuchar conexiones.
-                       sockbuf socket;
+                       sockinetbuf socket;
 
                        /// Conexiones de control.
                        ControllerList controllers;
 
                        /// Conexiones de control.
                        ControllerList controllers;
@@ -59,6 +59,11 @@ namespace Plaqui {
                        /// Transmisiones del estado de las plantas.
                        TransmitterList transmissions;
 
                        /// Transmisiones del estado de las plantas.
                        TransmitterList transmissions;
 
+                       /**
+                        * Entra en el loop para atender conexiones.
+                        */
+                       virtual void real_run(void);
+
                public:
 
                        /**
                public:
 
                        /**
diff --git a/Server/src/server_test.cpp b/Server/src/server_test.cpp
new file mode 100644 (file)
index 0000000..e0753b9
--- /dev/null
@@ -0,0 +1,61 @@
+// 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:  Sat Oct 18 18:18:36 2003
+// Autores: Leandro Lucarella <llucare@fi.uba.ar>
+//----------------------------------------------------------------------------
+//
+// $Id$
+//
+
+#include "server.h"
+#include <socket++/sockinet.h>
+#include <iostream>
+#include <sstream>
+#include <exception>
+
+using namespace std;
+using namespace Plaqui;
+
+int main(int argc, char* argv[]) {
+
+       // Termina con mas informacion si hay una excepcion no manejada.
+       std::set_terminate (__gnu_cxx::__verbose_terminate_handler);
+
+       // Necesita argumentos.
+       if (argc != 2) {
+               cerr << "Faltan argumentos: " << endl;
+               cerr << "\t" << argv[0] << " port" << endl;
+               return 1;
+       }
+
+       // Obtengo puerto.
+       unsigned port;
+       {
+               stringstream str(argv[1]);
+               str >> port;
+       }
+
+       // Corre el server.
+       Server server(port);
+       server.run(false);
+
+       return 0;
+}
index b8635fa6c7f5fbed0c53c441f72deb5886136642..bd6d06b32e9ca04d33e1bcd484d12147f03d43c1 100644 (file)
@@ -33,7 +33,18 @@ using namespace Plaqui;
 
 Transmitter::Transmitter(std::string host, int port):
                Connection(sockbuf::sock_dgram) {
 
 Transmitter::Transmitter(std::string host, int port):
                Connection(sockbuf::sock_dgram) {
-#warning Not implemented!
+       // FIXME - deberia ir en run().
        socket->connect(host.c_str(), port);
 }
 
        socket->connect(host.c_str(), port);
 }
 
+void Transmitter::real_run(void) {
+       // FIXME - debería tirar una excepción?
+       if (!socket->is_open()) {
+               std::cerr << "No se pudo conectar a " << socket->peerhost() <<
+                       ":" << socket->peerport() << "." << std::endl;
+       } else {
+               std::cerr << "Conectado a " << socket->peerhost() <<
+                       ":" << socket->peerport() << "." << std::endl;
+       }
+}
+
index 2100c1f995d19a21961ae453d104f44e414857b9..2b622b8fbdaeb2c3563ec77d514f862243eba7c0 100644 (file)
@@ -36,6 +36,13 @@ namespace Plaqui {
        /// Conexión para transmitir el estado de una planta.
        class Transmitter: public Connection {
 
        /// Conexión para transmitir el estado de una planta.
        class Transmitter: public Connection {
 
+               private:
+
+                       /**
+                        * Comienza a transmitir.
+                        */
+                       virtual void real_run(void);
+
                public:
 
                        /**
                public:
 
                        /**