ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
-STRIP_FROM_PATH = /home/luca/facultad/75.42/2003-2/final/Server/include \
- /home/luca/facultad/75.42/2003-2/final/Server/src
+STRIP_FROM_PATH = /home/luca/facultad/75.42/2003-2/final/Server/include/ \
+ /home/luca/facultad/75.42/2003-2/final/Server/
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = YES
/**
* Destructor.
*/
- virtual ~Connection(void) {}
+ virtual ~Connection(void);
/**
* Constructor.
private:
/**
- * Atiende la conexión.
+ * Realiza la conexión al servidor.
*/
virtual void real_run(void);
/**
* Destructor.
*/
- virtual ~ControlClient(void) {}
+ virtual ~ControlClient(void);
/**
* Constructor.
/**
* Destructor.
*/
- virtual ~ControlServer(void) {}
+ virtual ~ControlServer(void);
/**
* Constructor.
/// Conexión para recibir el estado de una planta.
class Receiver: public ServerConnection {
+ private:
+
+ /**
+ * Recibe la transmisión.
+ */
+ virtual void real_run(void);
+
public:
/**
* Destructor.
*/
- virtual ~Receiver(void) {}
+ virtual ~Receiver(void);
/**
* Constructor.
*/
Receiver(int port = 7528, std::string host = "localhost");
- /**
- * Recibe la transmisión.
- */
- virtual void run(void);
-
};
}
/// Thread en el cual correr la tarea.
Glib::Thread* thread;
- /// Indica si se debe frinalizar la tarea.
- bool stop;
-
/// Señal que indica que se finalizó la tarea.
SignalFinished finished;
+ protected:
+
+ /**
+ * Indica si se debe frinalizar la tarea.
+ *
+ * \todo Poner como privado y poner get() set() con locks.
+ */
+ bool stop;
+
// Métodos.
private:
/**
* Destructor.
*/
- virtual ~Runnable(void) {}
+ virtual ~Runnable(void);
/**
* Constructor.
// Métodos.
- private:
+ protected:
/**
- * Entra en el loop para atender conexiones.
+ * Obtiene una nueva \ref Connection "conexión".
+ *
+ * \param sd Descriptor del socket de la nueva conexión.
+ *
+ * \return Nueva conexión.
*/
- virtual void real_run(void);
+ virtual Connection* new_connection(const sockbuf::sockdesc& sd);
public:
/**
* Destructor.
*/
- virtual ~Server(void) {}
+ virtual ~Server(void);
/**
* Constructor.
*
* \todo Hacer un tipo Command abstracto o algo así.
*/
- void on_connection_command_received(void* command);
+ void on_control_command_received(void* command);
};
/**
* Destructor.
*/
- virtual ~ServerConnection(void) {}
+ virtual ~ServerConnection(void);
+
+ /**
+ * Constructor.
+ *
+ * \param socket Descriptor de socket a usar en la conexión.
+ */
+ ServerConnection(const sockbuf::sockdesc& sd);
+
+ /**
+ * Constructor.
+ *
+ * \param type Tipo de socket a usar.
+ */
+ ServerConnection(sockbuf::type type);
/**
* Obtiene la señal que avisa que se recibió un comando.
#ifndef PLAQUI_TCPSERVER_H
#define PLAQUI_TCPSERVER_H
-#include "plaqui/server/controlserver.h"
-#include "plaqui/server/transmitter.h"
+#include "plaqui/server/runnable.h"
+#include "plaqui/server/connection.h"
#include <socket++/sockinet.h>
-#include <string>
#include <list>
namespace PlaQui {
private:
/// Lista de conexiones de control.
- typedef std::list<Connnection*> ConnectionList;
+ typedef std::list<Connection*> ConnectionList;
// Atributos.
/**
* Destructor.
*/
- virtual ~TCPServer(void) {}
+ virtual ~TCPServer(void);
/**
* Constructor.
/**
* Destructor.
*/
- virtual ~Transmitter(void) {}
+ virtual ~Transmitter(void);
/**
* Constructor.
objects+=connection.o
connection.o: $(connection_h) connection.cpp
+serverconnection_h=$(connection_h) $(INCLUDE_DIR)/serverconnection.h
+objects+=serverconnection.o
+serverconnection.o: $(serverconnection_h) serverconnection.cpp
+
controlclient_h=$(connection_h) $(INCLUDE_DIR)/controlclient.h
objects+=controlclient.o
controlclient.o: $(controlclient_h) controlclient.cpp
objects+=transmitter.o
transmitter.o: $(transmitter_h) transmitter.cpp
-server_h=$(controlserver_h) $(transmitter_h) $(INCLUDE_DIR)/server.h
+tcpserver_h=$(connection_h) $(INCLUDE_DIR)/tcpserver.h
+objects+=tcpserver.o
+tcpserver.o: $(tcpserver_h) tcpserver.cpp
+
+server_h=$(tcpserver) $(controlserver_h) $(transmitter_h) \
+ $(INCLUDE_DIR)/server.h
objects+=server.o
server.o: $(server_h) server.cpp
//
#include "plaqui/server/controlclient.h"
-// XXX
-#include <iostream>
+#ifdef DEBUG
+# include <iostream>
+#endif // DEBUG
-using namespace PlaQui::Server;
+PlaQui::Server::ControlClient::~ControlClient(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": destructor." << std::endl;
+#endif // DEBUG
+}
-ControlClient::ControlClient(std::string host, int port):
+PlaQui::Server::ControlClient::ControlClient(std::string host, int port):
Connection(sockbuf::sock_stream) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": host" << host
+ << " | port = " << port << std::endl;
+#endif // DEBUG
// FIXME - poner en run().
socket->connect(host.c_str(), port);
}
-void ControlClient::real_run(void) {
+void PlaQui::Server::ControlClient::real_run(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": real_run." << std::endl;
+#endif // DEBUG
+#ifdef DEBUG
// FIXME - debería tirar una excepción?
if (!socket->is_open()) {
std::cerr << "No se pudo conectar a " << socket->peerhost() <<
} else {
std::cerr << "Conectado a " << socket->peerhost() <<
":" << socket->peerport() << "." << std::endl;
+#endif // DEBUG
}
}
}
PlaQui::Server::ControlServer::ControlServer(const sockbuf::sockdesc& sd):
- Connection(sd) {
+ PlaQui::Server::ServerConnection(sd) {
#ifdef DEBUG
std::cerr << __FILE__ << ": sd = " << sd.sock << std::endl;
#endif // DEBUG
//
#include "plaqui/server/receiver.h"
+#ifdef DEBUG
+# include <iostream>
+#endif // DEBUG
-using namespace PlaQui::Server;
+PlaQui::Server::Receiver::~Receiver(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": destructor." << std::endl;
+#endif // DEBUG
+}
-Receiver::Receiver(int port, std::string host):
- Connection(sockbuf::sock_dgram) {
+PlaQui::Server::Receiver::Receiver(int port, std::string host):
+ PlaQui::Server::ServerConnection(sockbuf::sock_dgram) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": port = " << port
+ << " | host = " << host << std::endl;
+#endif // DEBUG
// FIXME - deberia ir en run().
socket->bind(port);
}
-void Receiver::run(void) {
+void PlaQui::Server::Receiver::real_run(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": real_run." << std::endl;
+#endif // DEBUG
// FIXME - debería tirar una excepción?
if (!socket->is_open()) {
std::cerr << "No se pudo conectar a " << socket->peerhost() <<
# include <iostream>
#endif // DEBUG
-using namespace PlaQui::Server;
+const std::string
+PlaQui::Server::Request::CHARS_DIGIT = "0123456789";
-const std::string Request::CHARS_DIGIT = "0123456789";
+const std::string
+PlaQui::Server::Request::CHARS_LOWALPHA = "abcdefghijklmnopqrstuvwxyz";
-const std::string Request::CHARS_LOWALPHA = "abcdefghijklmnopqrstuvwxyz";
+const std::string
+PlaQui::Server::Request::CHARS_UPALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-const std::string Request::CHARS_UPALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+const std::string
+PlaQui::Server::Request::CHARS_ALPHA = CHARS_LOWALPHA + CHARS_UPALPHA;
-const std::string Request::CHARS_ALPHA = CHARS_LOWALPHA + CHARS_UPALPHA;
+const std::string
+PlaQui::Server::Request::CHARS_ALPHANUM = CHARS_DIGIT + CHARS_ALPHA;
-const std::string Request::CHARS_ALPHANUM = CHARS_DIGIT + CHARS_ALPHA;
+const std::string
+PlaQui::Server::Request::CHARS_RESERVED = ";/?:@&=+$,";
-const std::string Request::CHARS_RESERVED = ";/?:@&=+$,";
+const std::string
+PlaQui::Server::Request::CHARS_MARK = "-_.!~*'()";
-const std::string Request::CHARS_MARK = "-_.!~*'()";
+const std::string
+PlaQui::Server::Request::CHARS_UNRESERVED = CHARS_ALPHANUM + CHARS_MARK;
-const std::string Request::CHARS_UNRESERVED = CHARS_ALPHANUM + CHARS_MARK;
+const std::string
+PlaQui::Server::Request::CHARS_HEX = CHARS_DIGIT + std::string("abcdefABCDEF");
-const std::string Request::CHARS_HEX = CHARS_DIGIT + std::string("abcdefABCDEF");
-
-void Request::set_request(const std::string& req, const std::string& host,
- unsigned port) {
+void PlaQui::Server::Request::set_request(const std::string& req,
+ const std::string& host, unsigned port) {
#ifdef DEBUG
std::cerr << __FILE__ << ": req = " << req << " | host = " << host
<< " | port = " << port << std::endl;
#endif // DEBUG
- String request(req);
+ PlaQui::Server::String request(req);
(*this)["REMOTE_HOST"] = host;
std::stringstream ss;
ss << port;
throw "HTTP/1.1 501 Method Not Implemented";
}
// Averiguo método.
- std::string::size_type pos = request.find_first_of(String::SPACE_CHARS);
- String method = request.substr(0, pos);
+ std::string::size_type pos = request.find_first_of(
+ PlaQui::Server::String::SPACE_CHARS);
+ PlaQui::Server::String method = request.substr(0, pos);
if ((method.to_upper() == "GET") || (method.to_upper() == "POST")) {
(*this)["REQUEST_METHOD"] = method;
} else {
throw "HTTP/1.1 400 Bad Request";
}
// Si tiene más espacios, tengo la URI y el protocolo (o un error).
- pos = request.find_first_of(String::SPACE_CHARS);
+ pos = request.find_first_of(PlaQui::Server::String::SPACE_CHARS);
if (pos != std::string::npos) {
// Si el resto es un protocolo válido, agrego más variables.
- String protocol = request.substr(pos + 1);
+ PlaQui::Server::String protocol = request.substr(pos + 1);
protocol = protocol.trim();
- if ((String(protocol).to_upper() == "HTTP/1.0")
- || (String(protocol).to_upper() == "HTTP/1.1")) {
+ if ((PlaQui::Server::String(protocol).to_upper() == "HTTP/1.0")
+ || (PlaQui::Server::String(protocol).to_upper() == "HTTP/1.1")) {
(*this)["SERVER_PROTOCOL"] = protocol;
// Si no es un error.
} else {
(*this)["SCRIPT_NAME"] = request.substr(0, pos);
}
-void Request::parse_header(const std::string& header) {
+void PlaQui::Server::Request::parse_header(const std::string& header) {
#ifdef DEBUG
std::cerr << __FILE__ << ": header = " << header << std::endl;
#endif // DEBUG
# include <iostream>
#endif // DEBUG
+PlaQui::Server::Runnable::~Runnable(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": destructor." << std::endl;
+#endif // DEBUG
+}
+
PlaQui::Server::Runnable::Runnable(void): thread(0), stop(false) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": constructor." << std::endl;
+#endif // DEBUG
}
void PlaQui::Server::Runnable::static_run(PlaQui::Server::Runnable* runner) {
# include <iostream>
#endif // DEBUG
-using namespace PlaQui::Server;
+PlaQui::Server::Server::~Server(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": destructor." << std::endl;
+#endif // DEBUG
+}
-Server::Server(int port):
- socket(sockbuf::sock_stream) {
- socket.bind(port);
+PlaQui::Server::Server::Server(int port):
+ PlaQui::Server::Server::TCPServer(port) {
#ifdef DEBUG
- std::cerr << "Escuchando en " << socket.localhost() <<
- ":" << socket.localport() << "." << std::endl;
+ std::cerr << __FILE__ << ": port = " << port << std::endl;
#endif // DEBUG
- socket.listen();
}
-bool Server::start_transmission(std::string host, int port) {
+/// \todo Implementar.
+bool PlaQui::Server::Server::start_transmission(std::string host, int port) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": start_transmission(host = " << host
+ << " | port = " << port << ")" << std::endl;
+#endif // DEBUG
// TODO
return false;
}
-bool Server::stop_transmission(std::string host, int port) {
+/// \todo Implementar.
+bool PlaQui::Server::Server::stop_transmission(std::string host, int port) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": stop_transmission(host = " << host
+ << " | port = " << port << ")" << std::endl;
+#endif // DEBUG
// 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();
- }
+/// \todo Implementar.
+void PlaQui::Server::Server::on_control_command_received(void* command) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": on_control_command_received(command = "
+ << command << ")" << std::endl;
+#endif // DEBUG
}
#endif // DEBUG
}
-/*
PlaQui::Server::ServerConnection::ServerConnection(const sockbuf::sockdesc& sd):
- socket(sd) {
+ PlaQui::Server::Connection(sd) {
#ifdef DEBUG
std::cerr << __FILE__ << ": sd = " << sd.sock << std::endl;
#endif // DEBUG
}
PlaQui::Server::ServerConnection::ServerConnection(sockbuf::type type):
- socket(type) {
+ PlaQui::Server::Connection(type) {
#ifdef DEBUG
std::cerr << __FILE__ << ": type = " << type << std::endl;
#endif // DEBUG
}
-*/
PlaQui::Server::ServerConnection::SignalCommandReceived&
PlaQui::Server::ServerConnection::signal_command_received(void) {
# include <iostream>
#endif // DEBUG
-using namespace PlaQui::Server;
-
-const std::string String::SPACE_CHARS = " \t\n\r";
+const std::string PlaQui::Server::String::SPACE_CHARS = " \t\n\r";
-String::String(const std::string& str): std::string(str.c_str()) {
+PlaQui::Server::String::String(const std::string& str):
+ std::string(str.c_str()) {
}
-String& String::trim(const String& clist) {
+PlaQui::Server::String& PlaQui::Server::String::trim(
+ const PlaQui::Server::String& clist) {
erase(0, find_first_not_of(clist));
erase(find_last_not_of(clist) + 1);
return *this;
}
-String& String::to_lower(void) {
+PlaQui::Server::String& PlaQui::Server::String::to_lower(void) {
std::transform(begin(), end(), begin(), tolower);
return *this;
}
-String& String::to_upper(void) {
+PlaQui::Server::String& PlaQui::Server::String::to_upper(void) {
std::transform(begin(), end(), begin(), toupper);
return *this;
}
--- /dev/null
+// 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 "plaqui/server/tcpserver.h"
+#include <sigc++/class_slot.h> // FIXME
+#ifdef DEBUG
+# include <iostream>
+#endif // DEBUG
+
+PlaQui::Server::TCPServer::~TCPServer(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": destructor." << std::endl;
+#endif // DEBUG
+}
+
+PlaQui::Server::TCPServer::TCPServer(int port):
+ socket(sockbuf::sock_stream) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": port = " << port << std::endl;
+#endif // DEBUG
+ socket.bind(port);
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": escuchando en " << socket.localhost()
+ << ":" << socket.localport() << "." << std::endl;
+#endif // DEBUG
+ socket.listen();
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": [despues de listen()] escuchando en "
+ << socket.localhost() << ":" << socket.localport() << "." << std::endl;
+#endif // DEBUG
+}
+
+void PlaQui::Server::TCPServer::on_connection_finished(
+ PlaQui::Server::Connection* connection) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": on_connection_finished(connection = "
+ << connection << ")" << std::endl;
+#endif // DEBUG
+ // TODO: poner lock.
+ connections.remove(connection);
+ // TODO: sacar lock.
+}
+
+void PlaQui::Server::TCPServer::real_run(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": real_run" << std::endl;
+#endif // DEBUG
+ PlaQui::Server::Connection* conn;
+ while (!stop) {
+ // TODO: ver tema de timeout o como salir de un accept().
+ // Forma grasa de salir del accept: crear conexion que salga al toque.
+ conn = new_connection(socket.accept());
+ // TODO: poner lock.
+ connections.push_back(conn);
+ // TODO: sacar lock.
+ // TODO: esto va en Server::new_connection()
+ // Conecto la señal para cuando termina una conexión, borrarla.
+ conn->signal_finished().connect(
+ SigC::bind<PlaQui::Server::Connection*>(
+ SigC::slot_class(*this,
+ &PlaQui::Server::TCPServer::on_connection_finished),
+ conn));
+ conn->run();
+ }
+}
+
#include "plaqui/server/transmitter.h"
#include <socket++/sockinet.h>
#include <string>
+#ifdef DEBUG
+# include <iostream>
+#endif // DEBUG
-using namespace PlaQui::Server;
+PlaQui::Server::Transmitter::~Transmitter(void) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": destructor." << std::endl;
+#endif // DEBUG
+}
-Transmitter::Transmitter(std::string host, int port):
- Connection(sockbuf::sock_dgram) {
+/// \todo debría conectarse en real_run() (?)
+PlaQui::Server::Transmitter::Transmitter(std::string host, int port):
+ PlaQui::Server::Connection(sockbuf::sock_dgram) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": host = " << host
+ << " | port = " << port << std::endl;
+#endif // DEBUG
// FIXME - deberia ir en run().
socket->connect(host.c_str(), port);
}
-void Transmitter::real_run(void) {
+/// \todo debría dar una excepción (?)
+void PlaQui::Server::Transmitter::real_run(void) {
+#ifdef DEBUG
// FIXME - debería tirar una excepción?
if (!socket->is_open()) {
std::cerr << "No se pudo conectar a " << socket->peerhost() <<
std::cerr << "Conectado a " << socket->peerhost() <<
":" << socket->peerport() << "." << std::endl;
}
+#endif // DEBUG
}