]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Primera parte de práctica 3 terminada.
authorLeandro Lucarella <llucax@gmail.com>
Mon, 22 May 2006 15:48:54 +0000 (15:48 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Mon, 22 May 2006 15:48:54 +0000 (15:48 +0000)
13 files changed:
practicas/practica3/Makefile [new file with mode: 0644]
practicas/practica3/common/Makefile [new file with mode: 0644]
practicas/practica3/common/common.c [new file with mode: 0644]
practicas/practica3/common/common.h [new file with mode: 0644]
practicas/practica3/libtcp/Makefile [new file with mode: 0644]
practicas/practica3/libtcp/libtcp.c [new file with mode: 0644]
practicas/practica3/libtcp/libtcp.h [new file with mode: 0644]
practicas/practica3/parte1/Makefile [new file with mode: 0644]
practicas/practica3/parte1/client [new file with mode: 0755]
practicas/practica3/parte1/client.cpp [new file with mode: 0644]
practicas/practica3/parte1/protocol.h [new file with mode: 0644]
practicas/practica3/parte1/server.cpp [new file with mode: 0644]
practicas/practica3/parte1/serverhandler.cpp [new file with mode: 0644]

diff --git a/practicas/practica3/Makefile b/practicas/practica3/Makefile
new file mode 100644 (file)
index 0000000..8a2ef13
--- /dev/null
@@ -0,0 +1,19 @@
+
+SUBDIRS=libtcp common parte1
+
+.PHONY: clean
+all clean:
+       @set fnord $(MAKEFLAGS); amf=$$2; target=$@ ; \
+       dot_seen=no; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+       echo "Making $$target in $$subdir"; \
+       if test "$$subdir" = "."; then \
+       dot_seen=yes; \
+       local_target="$$target-am"; \
+       else \
+       local_target="$$target"; \
+       fi; \
+       (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+       || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done;
+
diff --git a/practicas/practica3/common/Makefile b/practicas/practica3/common/Makefile
new file mode 100644 (file)
index 0000000..cfd0c27
--- /dev/null
@@ -0,0 +1,16 @@
+
+TARGET=common.a
+LIBS=
+CFLAGS=-O0 -g
+CC=g++
+
+all: $(TARGET)
+
+$(TARGET): common.o
+       $(AR) cru $(TARGET) common.o
+
+common.o: common.h common.c
+
+.PHONY: clean
+clean:
+       rm -f *.o $(TARGET)
diff --git a/practicas/practica3/common/common.c b/practicas/practica3/common/common.c
new file mode 100644 (file)
index 0000000..b933cc7
--- /dev/null
@@ -0,0 +1,29 @@
+/* Released underOpen Software License v. 2.0
+ *
+ * This Open Software License (the "License") applies to any original work of authorship 
+ * (the "Original Work") whose owner (the "Licensor") has placed the following notice 
+ * immediately following the copyright notice for the Original Work:
+ *
+ *     Licensed under the Open Software License version 2.0
+ *
+ * See http://www.opensource.org/licenses/osl-2.0.php or the LICENSE file for more
+ * details.
+ */
+
+#include "common.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+void print_msg (FILE *fp, const char *fmt, ...)
+{
+       char linea[255];
+       va_list va;
+
+       va_start (va, fmt);
+               vsprintf(linea, fmt, va);
+       va_end (va);
+
+       write (fileno (fp), linea, strlen (linea));
+}
diff --git a/practicas/practica3/common/common.h b/practicas/practica3/common/common.h
new file mode 100644 (file)
index 0000000..a6652af
--- /dev/null
@@ -0,0 +1,21 @@
+/* Released underOpen Software License v. 2.0
+ *
+ * This Open Software License (the "License") applies to any original work of authorship 
+ * (the "Original Work") whose owner (the "Licensor") has placed the following notice 
+ * immediately following the copyright notice for the Original Work:
+ *
+ *     Licensed under the Open Software License version 2.0
+ *
+ * See http://www.opensource.org/licenses/osl-2.0.php or the LICENSE file for more
+ * details.
+ */
+
+#ifndef _ECHO_COMMON_H_
+#define _ECHO_COMMON_H_
+
+#include <stdio.h>
+
+void print_msg (FILE *fp, const char *fmt, ...);
+
+#endif // _ECHO_COMMON_H_
+
diff --git a/practicas/practica3/libtcp/Makefile b/practicas/practica3/libtcp/Makefile
new file mode 100644 (file)
index 0000000..61c1501
--- /dev/null
@@ -0,0 +1,17 @@
+# LibTcp - Internet stream version (TCP protocol)
+
+TARGET=libtcp.a
+LIBS=
+CFLAGS=-O0 -g
+CC=g++
+
+all: $(TARGET)
+
+$(TARGET): libtcp.o
+       $(AR) cru libtcp.a libtcp.o
+
+libtcp.o: libtcp.h libtcp.c
+
+.PHONY: clean
+clean:
+       rm -f *.o $(TARGET)
diff --git a/practicas/practica3/libtcp/libtcp.c b/practicas/practica3/libtcp/libtcp.c
new file mode 100644 (file)
index 0000000..9421dc6
--- /dev/null
@@ -0,0 +1,176 @@
+/* LibTcp - Released underOpen Software License v. 2.0
+ *
+ * This Open Software License (the "License") applies to any original work of authorship 
+ * (the "Original Work") whose owner (the "Licensor") has placed the following notice 
+ * immediately following the copyright notice for the Original Work:
+ *
+ *     Licensed under the Open Software License version 2.0
+ *
+ * See http://www.opensource.org/licenses/osl-2.0.php or the LICENSE file for more
+ * details.
+ */
+
+#include "libtcp.h"
+
+/** Abre un socket en modo activo para establecer una conexión con un servidor.
+ *
+ * Esta función es utilizada por los clientes para establecer una conexión TCP
+ * con un servidor. 
+ *
+ * \param servidor Nombre del host server
+ * \param port Número del puerto
+ * \return >0 El descriptor del socket, si se conecto al servidor.
+ * \return -2 Si no existe el nombre del servidor.
+ * \return -1 Si hubo error en la conexion y se debe consultar errno.
+ */
+int libtcp_open_activo (const char *server, int port)
+{
+       int sockfd; /* socket de la conexion */
+       struct sockaddr_in serv_addr;
+       struct hostent *ptr_server; /*puntero a dir del server(gethostbyname)*/
+
+       /* Borrar la estructura (poner en cero) */ 
+       bzero ((char *) &serv_addr, sizeof(serv_addr));
+       
+       /*      Inicializo familia de direcciones (protocolo IP) */
+       serv_addr.sin_family = AF_INET;
+
+       /* Cargar port en el socket: Convertir Host-TO-Network-Short integer */
+       serv_addr.sin_port = htons (port);
+
+       /* Cargo dirección del server en el socket. Convertir nombre del host en su direccion */
+       ptr_server = gethostbyname (server); 
+       if (ptr_server == NULL) {
+               /* No existe nombre de host. Posible falla en resolución de nombre */
+               return -2;
+       }
+       memcpy (&serv_addr.sin_addr, ptr_server->h_addr, ptr_server->h_length);
+
+       /* Abro como un socket de TCP (Internet stream socket) */
+       if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
+               /* Error en la creacion del socket */
+               return -1;
+       }
+
+       if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+               /* TODO : Deberia ser un codigo de error diferente, asi puedo diferenciarlos */
+               return -1;
+       }
+
+  return sockfd;
+}
+
+/** Abre un socket en modo pasivo usando protocolo TCP.
+ *
+ * La función se encarga de inicializar y crear el socket, y
+ * luego enlazarla con el SO.
+ * 
+ * \param port Puerto sobre el cual atiende este servidor
+ * \return >0 El socket, si la operacion fue exitosa
+ * \return <0 Si hubo un error (ver errno)
+ */
+int libtcp_open_pasivo (int port)
+{
+       char mostrar[80]; /* mensajes en la pantalla */ 
+       int     sockfd; /* socket que sirve como template */ 
+       struct sockaddr_in      serv_addr;
+
+       bzero ((char *)&serv_addr, sizeof (serv_addr));
+       serv_addr.sin_family = AF_INET; /* Familia protocolos TCP/IP */
+       serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); /* Cualquier cliente */ 
+       serv_addr.sin_port = htons ((u_short)port); /* Port en formato red */
+
+       /* Crea un socket para TCP (un Internet stream socket) */
+       if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
+               return -1;
+       }
+
+       sprintf (mostrar, "LibTcp::ServerPasivo: socket creado %d\n", sockfd);
+       write (fileno(stdout), mostrar, strlen (mostrar));
+
+       /* Vincular el socket con la direccion local */
+       if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
+               return -1;
+       }
+
+       sprintf (mostrar, "LibTcp::Server: se hizo el bind\n");
+       write(fileno(stdout), mostrar, strlen(mostrar));
+
+  /* Definir la cola de espera = hasta 5 clientes */
+       listen(sockfd, 5);
+
+       sprintf (mostrar, "LibTcp::Server: se hizo el listen con el socket %d\n", sockfd);
+       write(fileno(stdout), mostrar, strlen(mostrar));
+
+       return sockfd;
+}
+
+/** Lee de a un byte por vez a un buffer hasta encontrar un "\n".
+ * 
+ *  La cadena leída es terminada en "\0".
+ *
+ *  \return El tamaño, en caracteres, de la cadena leida.
+ *     \param fd       Descriptor del socket
+ *     \param ptr Puntero al buffer 
+ *     \param maxlong Tamaño del buffer (en bytes)
+ *     \TODO Soporte de caracteres multibyte
+ */
+int libtcp_receive (int fd, char *ptr, unsigned int maxlong)
+{
+       int     n, car;
+       char    c;
+
+       for (n = 0; n < maxlong; n++) {
+               if ((car = read (fd, &c, sizeof (char))) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;
+                       } else if (car == 0) {
+                               if (n == 1)
+                                       /* EOF, sin datos leidos */
+                                       return 0;
+                               else
+                                       break;          /* EOF, se leyo algo */
+               } else
+                       return -1;
+       }
+
+       *ptr = '\0';
+       return n;
+}
+
+/** Lee una informacion binaria */
+int libtcp_receive_bin (int fd, void *ptr, unsigned int maxlong)
+{
+       return read (fd, ptr, maxlong);
+}
+
+
+/** Escribe n bytes sobre un descriptor.
+ *
+ *  Si no se escribieron n bytes, trata de repetir hasta que se hayan escrito
+ *  los n bytes.
+ *
+ *  Se debe usar esta funcion cuando el descriptor en un stream socket.
+ *  
+ *     \param fd Descriptor del socket
+ *     \param ptr Puntero al mensaje
+ *     \param n cantidad de bytes
+ */
+int libtcp_send (int fd, const char *ptr, unsigned int n)
+{
+       int     nfaltan, nenviados;
+
+       nfaltan = n;
+       while (nfaltan > 0) {
+               nenviados = write (fd, ptr, nfaltan);
+               if (nenviados <= 0)
+                       return nenviados;
+
+               nfaltan -= nenviados;
+               ptr     += nenviados;
+       }
+
+       return n - nfaltan;
+}
+
diff --git a/practicas/practica3/libtcp/libtcp.h b/practicas/practica3/libtcp/libtcp.h
new file mode 100644 (file)
index 0000000..83754c0
--- /dev/null
@@ -0,0 +1,40 @@
+/* LibTcp - Released underOpen Software License v. 2.0
+ *
+ * This Open Software License (the "License") applies to any original work of authorship 
+ * (the "Original Work") whose owner (the "Licensor") has placed the following notice 
+ * immediately following the copyright notice for the Original Work:
+ *
+ *     Licensed under the Open Software License version 2.0
+ *
+ * See http://www.opensource.org/licenses/osl-2.0.php or the LICENSE file for more
+ * details.
+ */
+
+#ifndef _LIBTCP_COMMON_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#define        LIBTCP_DEFAULT_UDP_PORT 5000
+#define        LIBTCP_DEFAULT_TCP_PORT 5000
+
+extern int errno;
+
+int libtcp_open_activo (const char *server, int port);
+int libtcp_open_pasivo (int port);
+int libtcp_receive (int fd, char *ptr, unsigned int maxlong);
+int libtcp_receive_bin (int fd, void *ptr, unsigned int maxlong);
+int libtcp_send (int fd, const char *ptr, unsigned int n);
+
+#endif // _LIBTCP_COMMON_H_
+
diff --git a/practicas/practica3/parte1/Makefile b/practicas/practica3/parte1/Makefile
new file mode 100644 (file)
index 0000000..3ca38ce
--- /dev/null
@@ -0,0 +1,27 @@
+
+CLIENTE=client
+SERVER_ITER=serverhandler
+SERVER_REAL=server
+LIBS=../libtcp/libtcp.a ../common/common.a
+CFLAGS=-g -Wall -I../libtcp -I../common
+CXXFLAGS=$(CFLAGS)
+TARGET=$(CLIENTE) $(SERVER_ITER) $(SERVER_REAL)
+CC=g++
+
+all: $(TARGET)
+
+$(CLIENTE): client.o $(LIBS)
+
+client.o: client.cpp
+
+$(SERVER_ITER): serverhandler.o $(LIBS)
+
+serverhandler.o: serverhandler.cpp
+
+$(SERVER_REAL): server.o $(LIBS)
+
+server.o: server.cpp
+
+.PHONY: clean
+clean:
+       rm -f *.o $(TARGET)
diff --git a/practicas/practica3/parte1/client b/practicas/practica3/parte1/client
new file mode 100755 (executable)
index 0000000..a4bf073
Binary files /dev/null and b/practicas/practica3/parte1/client differ
diff --git a/practicas/practica3/parte1/client.cpp b/practicas/practica3/parte1/client.cpp
new file mode 100644 (file)
index 0000000..2f2594d
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Cliente que envía operaciones al hash del servidor.
+ */
+
+#include "libtcp.h"
+#include "common.h"
+#include "protocol.h"
+#include <string>
+#include <sstream>
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+    int sockfd;
+    int client_id;
+    char *server_name;
+    char *localhost = "localhost";
+    pid_t pid;
+    int port;
+    const char *pname = argv[0];
+
+    // mostrar el pid del cliente
+    pid = getpid();
+    print_msg(stdout, "%s Cliente con pid = %d\n", pname, pid);
+
+    // Verifico parametros de linea de comandos
+    if (argc > 2) 
+        port = atoi (argv[2]);
+    else
+        port = LIBTCP_DEFAULT_TCP_PORT;
+
+    if (port <= 0)
+    {
+        // valor incorrecto: aviso y terminar
+        print_msg(stdout, "%s (%d): Nro. de port invalido %d\n", pname, pid, port);
+        exit(1);
+    }
+
+    if (argc > 1)
+        server_name = argv[1];
+    else
+        server_name = localhost;
+
+    // id del cliente, por default calculado en base al pid
+    if (argc > 3)
+        client_id = atoi(argv[3]);
+    else
+        client_id = pid % 32;
+
+    // Abro el socket
+    sockfd = libtcp_open_activo(server_name, port); 
+    if (sockfd < 0)
+    {
+        // ERROR
+        if (sockfd == -2)
+        {
+            print_msg(stdout, "%s (%d): Nombre de server no existe %s\n", pname, pid, server_name);
+            exit(1);
+        }
+        else
+        {
+            perror("Error al llamar a libtcp_open_activo");
+            exit(1);
+        }
+    }
+
+    std::string line;
+    Protocol::Type type;
+    while (std::getline(std::cin, line))
+    {
+        std::istringstream iss(line);
+        std::string token;
+        if (!(iss >> token)) return 0;
+        if (token == "put")
+        {
+            type = Protocol::PUT;
+        }
+        else if (token == "find")
+        {
+            type = Protocol::FIND;
+        }
+        else if (token == "del")
+        {
+            type = Protocol::DEL;
+        }
+        else
+        {
+            print_msg(stderr, "%s (%d): Invalid token %s!\n", pname, pid, token.c_str());
+            exit(1);
+        }
+        while (iss >> token)
+        {
+            Protocol proto(type, 0, client_id, token.size());
+            print_msg(stdout, "%s (%d): escribiendo %s\n", pname, pid, token.c_str());
+            if (libtcp_send(sockfd, (char*) &proto, sizeof(Protocol)) != sizeof(Protocol)
+                    || libtcp_send(sockfd, token.c_str(), token.size()) != token.size())
+            {
+                print_msg(stderr, "%s (%d): error en envio sobre el socket\n", pname, pid);
+                exit(1);
+            }
+        }
+        Protocol proto(type, 1, client_id, 0);
+        if (libtcp_send(sockfd, (char*) &proto, sizeof(Protocol)) != sizeof(Protocol))
+        {
+            print_msg(stderr, "%s (%d): error en envio sobre el socket\n", pname, pid);
+            exit(1);
+        }
+        // Esperando respuesta del servidor con el resultado
+        int response;
+        int n = libtcp_receive(sockfd, (char*) &response, sizeof(response));
+        if (n < 0)
+        {
+            print_msg(stderr, "%s (%d): error en recibir\n", pname, pid);
+        }
+        else
+        {
+            print_msg(stdout, "%s (%d): el server responde %d\n", pname, pid, response);
+        }
+    }
+
+    Protocol proto(Protocol::QUIT, 1, client_id, 0);
+    if (libtcp_send(sockfd, (char*) &proto, sizeof(Protocol)) != sizeof(Protocol))
+    {
+        print_msg(stderr, "%s (%d): error en envio sobre el socket\n", pname, pid);
+        exit(1);
+    }
+
+    /* Limpio y salgo */
+    close(sockfd);    
+    return EXIT_SUCCESS;
+}
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/practica3/parte1/protocol.h b/practicas/practica3/parte1/protocol.h
new file mode 100644 (file)
index 0000000..f64a8b0
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _PROTOCOL_H_
+#define _PROTOCOL_H_
+
+struct Protocol
+{
+    enum Type { PUT, FIND, DEL, QUIT };
+    enum Result { OK, NOT_FOUND, EXISTS };
+
+    unsigned char type: 2;       // 2 bits para tipo
+    unsigned char end: 1;        // 1 bit para marca de FIN
+    unsigned char client_id: 5;  // 5 bits para id de cliente
+    unsigned char len;           // 255 máximo
+
+    Protocol() {}
+
+    Protocol(unsigned type, unsigned end, unsigned client_id, unsigned len):
+        type(type), end(end), client_id(client_id), len(len) {}
+
+};
+
+#endif // _PROTOCOL_H_
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/practica3/parte1/server.cpp b/practicas/practica3/parte1/server.cpp
new file mode 100644 (file)
index 0000000..b445c0e
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Server concurrente usando protocolo TCP para manipular un set.
+ */
+
+#include "libtcp.h"
+#include "common.h"
+#include <csignal>
+
+void fin_hijos(int);
+
+int main (int argc, char *argv[])
+{
+    static char el_socket[15]; /* string que contiene el socket para el servidor de eco */
+
+    int sockfd;    /* socket que sirve como template */ 
+    int newsockfd; /* socket conectado al cliente */
+    int port;
+    unsigned int clilen; /* longitud dir. cliente */
+    unsigned int childpid; /* pid del hijo */
+    struct sockaddr_in cli_addr;
+
+    /* Verifico parametros de linea de comandos */
+    if (argc > 1)
+        port = atoi(argv[1]);
+    else
+        port = LIBTCP_DEFAULT_TCP_PORT;
+
+
+    /* Inicia Servidor - Open Pasivo */
+    if ((sockfd = libtcp_open_pasivo(port)) < 0)
+    {
+        perror("Server: no se puede abrir el stream socket");
+        exit(1);
+    }
+
+    print_msg(stdout, "server: se hizo el open pasivo, socket %d\n", sockfd);
+
+    signal(SIGCHLD, fin_hijos);
+
+    /* PROCESAMIENTO DEL SERVER */
+    while (1)
+    {
+        clilen = sizeof(cli_addr);
+        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
+        if (newsockfd < 0)
+        {
+            perror("server: error en el accept");
+            exit(1); 
+        }
+
+        if ((childpid = fork()) < 0)
+        { 
+            perror("server: error en el fork");
+            exit(1);
+        }
+        else if (childpid == 0)
+        {
+            /* PROCESO HIJO (child) que atiende al cliente */
+            close(sockfd); /* cerramos socket original */
+
+            print_msg(stdout, "server: socket armado con un cliente  %d\n", newsockfd);
+
+            /* pasarle el socket al hijo que atiende */
+            sprintf(el_socket, "%d\n", newsockfd);
+
+            /* Se lanza el proceso que atiende a ese cliente */
+            execlp("./serverhandler", "./serverhandler", el_socket, (char *)0);
+            perror("Server: error al lanzar el handler del servidor.");
+            exit(3);
+        }
+
+        /* PROCESO PADRE, se prepara para recibir otro cliente */
+        /* cerrar el socket pasado al hijo */
+        close(newsockfd);
+    }
+}
+
+/** Elimina Procesos-hijos que terminaron */
+void fin_hijos(int) 
+{
+    union wait status;
+    while (wait3((int *)&status, WNOHANG, (struct rusage *)0) >= 0);
+}
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/practica3/parte1/serverhandler.cpp b/practicas/practica3/parte1/serverhandler.cpp
new file mode 100644 (file)
index 0000000..d21a327
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Servidor de hash
+ */
+
+#include "libtcp.h"
+#include "common.h"
+#include "protocol.h"
+#include <set>
+#include <string>
+#include <cstdlib>
+
+int main(int argc, char *argv[])
+{
+    char *pname;
+    int sockfd;/* socket que sirve como template */ 
+    pid_t pid; /* pid del server iterativo */
+    char linea[256];
+    char fin = 0, fin_cmd = 0;
+    int result = 0;
+    std::set< std::string > set;
+
+    pname = argv[0];
+    pid = getpid();
+
+    /* Verifico parametros de linea de comando */
+    if (argc > 1)
+        sockfd = atoi(argv[1]);
+    else
+    {
+        perror("Falta parametro con fd");
+        exit (1);
+    }
+
+    print_msg(stdout, "%s (%d): atendiendo a cliente por socket %d\n", pname, pid, sockfd);
+
+    while (!fin)
+    {
+        std::string buffer;
+        while (!fin_cmd)
+        {
+            Protocol proto;
+            int n = libtcp_receive_bin(sockfd, (char*) &proto, sizeof(Protocol));
+            if (n < 0)
+            {
+                print_msg(stdout, "%s (%d): error en recibir\n", pname, pid);
+                exit(1);
+            }
+            print_msg(stdout, "%s (%d): cliente %d envio operacion (%d, %d, %d)\n",
+                    pname, pid, proto.client_id, proto.type, proto.end, proto.len);
+
+            n = libtcp_receive_bin(sockfd, linea, proto.len);
+            if (n < 0)
+            {
+                print_msg(stdout, "%s (%d): error en recibir\n", pname, pid);
+                exit(1);
+            }
+            linea[proto.len] = '\0';
+            print_msg(stdout, "%s (%d): se recibieron %d bytes de payload (%s)\n",
+                    pname, pid, proto.len, linea);
+            buffer += linea;
+            print_msg(stdout, "%s (%d): buffer: %s\n", pname, pid, buffer.c_str());
+
+            if (proto.end)
+            {
+                switch (proto.type)
+                {
+                    case Protocol::PUT:
+                        if (set.find(buffer) == set.end())
+                        {
+                            set.insert(buffer);
+                            result = Protocol::OK;
+                        }
+                        else
+                            result = Protocol::EXISTS;
+                        break;
+                    case Protocol::FIND:
+                        if (set.find(buffer) == set.end())
+                            result = Protocol::NOT_FOUND;
+                        else
+                            result = Protocol::OK;
+                        break;
+                    case Protocol::DEL:
+                        if (set.erase(buffer))
+                            result = Protocol::OK;
+                        else
+                            result = Protocol::NOT_FOUND;
+                        break;
+                    case Protocol::QUIT:
+                        print_msg(stdout, "%s (%d): Say no more\n", pname, pid);
+                        fin = 1;
+                        fin_cmd = 1;
+                        break;
+                    default:
+                        print_msg(stderr, "%s (%d): Operacion no soportada\n", pname, pid);
+                }
+                buffer.clear();
+                fin_cmd = 1;
+            }
+        }
+        fin_cmd = 0;
+
+        // Envío respuesta
+        libtcp_send(sockfd, (char*) &result, sizeof(int));
+        print_msg(stdout, "%s (%d) FIN (resultado = %d)\n", pname, pid, result);
+    }
+
+    close(sockfd);
+
+}
+
+// vim: set et sw=4 sts=4 :