Advertisement
Guest User

server

a guest
Oct 11th, 2016
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.96 KB | None | 0 0
  1. #include <iostream>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <pthread.h>
  7. #include <unordered_map>
  8. #include <vector>
  9. #include "auxiliares.h"
  10. #include "Mensaje.h"
  11. #include "Log.h"
  12. #include <SDL2/SDL.h>
  13. #include "ProtocoloComando.h"
  14. #include "ProtocoloVistaUpdate.h"
  15. #include "Personaje.h"
  16. #define MAX_CLIENTS 6
  17.  
  18. using namespace std;
  19.  
  20. struct argthread {
  21.     int clientFD= 0;
  22.     pthread_t* thread= NULL;
  23.     char* user=NULL;
  24.     char* clave= NULL;
  25. };
  26.  
  27.  
  28. class NoSePudoCrearServidorException : public runtime_error {
  29.  
  30. public:
  31.     NoSePudoCrearServidorException() : runtime_error("No se pudo crear el servidor") {
  32.     }
  33.  
  34. };
  35.  
  36.  
  37. class Servidor {
  38.  
  39. private:
  40.     static int fileDescrpt;
  41.     string nombreArchivoCsv;
  42.     struct sockaddr_in serv_addr, cli_addr;
  43.     socklen_t pesoCli_adrr;
  44.     pthread_t threadControl;
  45.     pthread_attr_t attr;
  46.     bool serverOn = false;
  47.     static vector<argthread_t *> conectados;
  48.     static unordered_map<string, string> usuarios;
  49.     static vector<Mensaje> mensajes;
  50.     static pthread_mutex_t mutex_mensajes;
  51.     static pthread_mutex_t mutex_login;
  52.     static Log logger;
  53.     static Personaje personaje;
  54.  
  55.     static void *controlInput(void *serverStatus) {
  56.  
  57.         cout << "ESPERANDO CLIENTES" << endl << "Presione * para salir..." << endl;
  58.  
  59.         string input;
  60.         while (true) {
  61.             cin >> input;
  62.  
  63.             if (input.compare("*") == 0) {
  64.                 *((bool *) serverStatus) = false;
  65.                 cerrarConexiones();
  66.                 usleep(100000);
  67.                 shutdown(fileDescrpt, SHUT_RDWR);
  68.                 return NULL;
  69.             }
  70.         }
  71.     }
  72.  
  73.     static void cerrarConexiones() {
  74.         size_t numConexiones = conectados.size();
  75.  
  76.         for (size_t i = 0; i < numConexiones; i++) {
  77.             argthread_t *actual = conectados[i];
  78.             shutdown(actual->clientFD, SHUT_RDWR);
  79.         }
  80.     }
  81.  
  82.     void cargarUsuarios(string filename) {
  83.  
  84.         char* linea = NULL;
  85.         size_t len = 0;
  86.         FILE *archivo = fopen(filename.c_str(), "r");
  87.  
  88.         while (getline(&linea, &len, archivo) != -1) {
  89.             string usuario = strtok(linea, ",");
  90.             string password = strtok(NULL, ",");
  91.             usuarios[usuario] = password;
  92.             free(linea);
  93.             linea = NULL;
  94.         }
  95.  
  96.         free(linea);
  97.         fclose(archivo);
  98.     }
  99.  
  100.     static bool esValido(string usuario, string clave) {
  101.         cout << usuario << " " << clave << endl;
  102.         usuario.erase(usuario.length() - 1);
  103.         if (usuarios.find(usuario) == usuarios.end())
  104.             return false;
  105.  
  106.         return (usuarios[usuario] == clave);
  107.     }
  108.  
  109.     static bool pedirLogin(FILE *mensajeCliente, argthread_t *arg) {
  110.  
  111.         size_t len = 0;
  112.         char* user = NULL;
  113.         char* pass = NULL;
  114.         ssize_t bytesLeidos=0;
  115.  
  116.         // Pido el usuario al cliente
  117.         bytesLeidos=getline(&user, &len, mensajeCliente);
  118.         if (bytesLeidos<=0){
  119.             perror("ERROR --> Al leer nombre de usuario\n");
  120.             return false;
  121.         }
  122.         bytesLeidos=getline(&pass, &len, mensajeCliente);
  123.         if (bytesLeidos<=0){
  124.             perror("ERROR --> Al leer contrasena\n");
  125.             return false;
  126.         }
  127.  
  128.          int result = pthread_mutex_lock(&mutex_login);
  129.          if (result != 0) perror("Fallo el pthread_mutex_lock en login");
  130.  
  131.         // Chequeo si el user ya esta conectado
  132.         vector<argthread_t *>::iterator it;
  133.         for (it = conectados.begin(); it != conectados.end();) {
  134.             if (it.operator*()->user != NULL){
  135.                 if (strcmp(it.operator*()->user,user) == 0){
  136.                     cout << user << "Ya esta conectado" << endl;
  137.                     free(user);
  138.                     free(pass);
  139.                     result = pthread_mutex_unlock(&mutex_login);
  140.                     if (result != 0) perror("Fallo el pthread_mutex_unlock en login");
  141.                     return false;
  142.                 }
  143.             }
  144.             it++;
  145.         }
  146.  
  147.         string user_s(user);
  148.         string pass_s(pass);
  149.  
  150.         if (esValido(user_s, pass_s)){
  151.             arg->user = user;
  152.             arg->clave = pass;
  153.             result = pthread_mutex_unlock(&mutex_login);
  154.             if (result != 0) perror("Fallo el pthread_mutex_unlock en login");
  155.             return true;
  156.         }
  157.  
  158.         cout << "User o pass fallidos" << endl;
  159.         free(user);
  160.         free(pass);
  161.         result = pthread_mutex_unlock(&mutex_login);
  162.         if (result != 0) perror("Fallo el pthread_mutex_unlock en login");
  163.         return false;
  164.     }
  165.  
  166.     static void mandarUsuarios(int sockNewFileDescrpt) {
  167.         //Consigo las claves del hash de usuarios
  168.         vector<string> keys;
  169.         for (auto kv : usuarios) {
  170.             keys.push_back(kv.first);
  171.         }
  172.  
  173.         //Los junto en un vector separados por un espacio
  174.         string texto;
  175.         for (int i = 0; i < keys.size(); i++) {
  176.             texto += keys[i] + ",";
  177.         }
  178.         texto += "\n";
  179.  
  180.         //Transformo string en char*
  181.         char *textoUsuarios = new char[texto.length() + 1];
  182.         strcpy(textoUsuarios, texto.c_str());
  183.  
  184.         //Mando el vector al cliente
  185.         ssize_t bytesEscritos = write(sockNewFileDescrpt, textoUsuarios, strlen(textoUsuarios));
  186.         delete textoUsuarios;
  187.  
  188.         if (bytesEscritos < 0)
  189.             perror("ERROR --> No se pudo responder al cliente");
  190.     }
  191.  
  192.     static void kickearUsuario(argthread_t* arg) {
  193.  
  194.         vector<argthread_t*>::iterator it;
  195.  
  196.         int result = pthread_mutex_lock(&mutex_login);
  197.         if (result != 0) perror("Fallo el pthread_mutex_lock en kick");
  198.  
  199.         for (it = conectados.begin(); it != conectados.end();) {
  200.  
  201.             if (it.operator*()->user == NULL){
  202.                 it = conectados.erase(it);
  203.                 result = pthread_mutex_unlock(&mutex_login);
  204.                 if (result != 0) perror("Fallo el pthread_mutex_unlock en kick");
  205.                 return;
  206.             }
  207.  
  208.             else if (it.operator*()->user != NULL && arg->user != NULL){
  209.                 if (strcmp(it.operator*()->user, arg->user) == 0){
  210.                     free(it.operator*()->user);
  211.                     free(it.operator*()->clave);
  212.                     it = conectados.erase(it);
  213.                     result = pthread_mutex_unlock(&mutex_login);
  214.                     if (result != 0) perror("Fallo el pthread_mutex_unlock en kick");
  215.                     return;
  216.                 }
  217.             }
  218.  
  219.             it++;
  220.         }
  221.  
  222.         result = pthread_mutex_unlock(&mutex_login);
  223.         if (result != 0) perror("Fallo el pthread_mutex_unlock en kick");
  224.     }
  225.  
  226.     static void agregarMensaje(char* emisorChar, char *textoInicial, ssize_t largo, bool mover) {
  227.  
  228.         if (textoInicial == NULL){
  229.             printf("ERROR");
  230.             exit(1);
  231.         }
  232.  
  233.         string emisor(emisorChar);
  234.         emisor.erase(emisor.length()-1);
  235.  
  236.         int key;
  237.         int pressed;
  238.         string stream(&textoInicial[6]); //Esto hace magia NO TOCAR
  239.  
  240.         ProtocoloComando::parse(stream, &key, &pressed);
  241.  
  242.         ProtocoloVistaUpdate update;
  243.         int aux;
  244.  
  245.         cout << pressed << endl;
  246.  
  247.         if ( pressed == 1 && !mover ) {
  248.             //Adjust the velocity
  249.             switch( key ) {
  250.  
  251.                 case SDLK_LEFT:
  252.                     // ToDo Actualizar personaje logico (con el nombre de usuario identifico que personaje tengo que actualizar)
  253.                     personaje.setVelx(-personaje.getPersonaje_VEL());
  254.                     break;
  255.  
  256.                 case SDLK_RIGHT:
  257.                     personaje.setVelx(personaje.getPersonaje_VEL());
  258.  
  259.                    // cout << "SE MOVIO " << personaje.getSeMovio() << endl;
  260.                    // cout << "POSX " << personaje.getPosx() << endl;
  261.                     //cout << "POSY " << personaje.getPosy() << endl;
  262.  
  263.                     break;
  264.  
  265.                 case SDLK_UP:
  266.                     //if (!saltando) saltando=true;
  267.                     //subiendo=true;*/
  268.                     break;
  269.  
  270.                 default:
  271.                     cout << "ESTOY EN DEFAULT DOWN" << endl;
  272.                     cout << key << endl;
  273.             }
  274.         }
  275.  
  276.         else if ( pressed == 0 && !mover) {
  277.  
  278.             //Adjust the velocity
  279.             switch( key ) {
  280.  
  281.                 case SDLK_LEFT:
  282.                     personaje.setVelx(personaje.getPersonaje_VEL());
  283.                     break;
  284.  
  285.                 case SDLK_RIGHT:
  286.                     personaje.setVelx(-personaje.getPersonaje_VEL());
  287.                     break;
  288.  
  289.                 case SDLK_UP:
  290.                     break;
  291.  
  292.                 default:
  293.                     cout << "ESTOY EN DEFAULT UP" << endl;
  294.                     cout << key << endl;
  295.             }
  296.         }
  297.         //cout << mover << " MOVER" << endl;
  298.         if (mover) {
  299.             personaje.mover();
  300.  
  301.         }
  302.         update.setEstado(personaje.getSeMovio());
  303.         update.setX(personaje.getPosx());
  304.         update.setY(personaje.getPosy());
  305.         update.setObject_id(1);
  306.         int result; // para el mutex
  307.  
  308.         //cout << "TO STRING" << endl;
  309.  
  310.         //cout << personaje.getSeMovio() << endl;
  311.         //cout << personaje.getPosx() << endl;
  312.         //cout << personaje.getPosy() << endl;
  313.  
  314.         string mensaje = update.toString();
  315.  
  316.         cout << mensaje;
  317.  
  318.         // ToDo Encolar el UpdateVista que se creo en alguno de los case de arriba
  319.         for (auto kv : usuarios) {
  320.             Mensaje mensajeNuevo(emisor, kv.first, mensaje);
  321.  
  322.             // Lockeo el mutex a mensajes
  323.             result = pthread_mutex_lock(&mutex_mensajes);
  324.             if (result != 0) perror("Fallo el pthread_mutex_lock en agregar msjs (a todos)");
  325.             logger.loggearMsj(emisor, kv.first, mensaje);
  326.  
  327.             mensajes.push_back(mensajeNuevo);
  328.  
  329.             // Unlockeo el mutex a mensajes
  330.             result = pthread_mutex_unlock(&mutex_mensajes);
  331.             if (result != 0) perror("Fallo el pthread_mutex_lock en agregar msjs (a todos)");
  332.         }
  333.  
  334.     }
  335.  
  336.     static bool enviarMensaje(argthread_t* arg, char* linea, ssize_t* bytesLeidos, bool mover) {
  337.  
  338.         if (*bytesLeidos < 0) {
  339.             cout << " SE DESCONECTÓ " << arg->user << endl;
  340.             free(linea);
  341.             return false;
  342.         }
  343.  
  344.         agregarMensaje(arg->user, linea, *bytesLeidos, mover);
  345.         return true;
  346.  
  347.     }
  348.  
  349.     static void recibirMensajes(argthread_t* arg, ssize_t* bytesEscritos, int sockNewFileDescrpt) {
  350.  
  351.         string receptor(arg->user);
  352.         receptor.erase(receptor.length() - 1);
  353.         vector<Mensaje>::iterator it;
  354.  
  355.         int result; //para el mutex
  356.  
  357.         // Lockeo el mutex a mensajes
  358.         result = pthread_mutex_lock(&mutex_mensajes);
  359.  
  360.         if (result != 0)
  361.             perror("Fallo el pthread_mutex_lock en agregar msjs (a todos)");
  362.  
  363.         logger.loggearRecepcion(receptor);
  364.  
  365.         for (it = mensajes.begin(); it != mensajes.end();) {
  366.             if (it->getNameReceptor() == receptor) {
  367.  
  368.                 string mensajeEmisor = it->getMensaje();
  369.                 const char* mensajeChar = mensajeEmisor.c_str();
  370.  
  371.                 *bytesEscritos = write(sockNewFileDescrpt, mensajeChar, mensajeEmisor.length());
  372.  
  373.                 if (*bytesEscritos < 0) {
  374.                     perror("ERROR --> Cliente se desconectó inesperadamente");
  375.                     break;
  376.                 }
  377.                 it = mensajes.erase(it);
  378.  
  379.                 // Unlockeo el mutex a mensajes
  380.                 result = pthread_mutex_unlock(&mutex_mensajes);
  381.                 if (result != 0) perror("Fallo el pthread_mutex_lock en agregar msjs (a todos)");
  382.  
  383.                 return;
  384.             }
  385.             else it++;
  386.         }
  387.  
  388.         // Unlockeo el mutex a mensajes
  389.         result = pthread_mutex_unlock(&mutex_mensajes);
  390.         if (result != 0)
  391.             perror("Fallo el pthread_mutex_lock en agregar msjs (a todos)");
  392.  
  393.         const char* fin = "$\n";
  394.  
  395.         if (*bytesEscritos >= 0)
  396.             if (write(sockNewFileDescrpt, fin, strlen(fin)) < 0 ) {
  397.                 perror("ERROR --> Escritura de fin de mensajes");
  398.                 // ToDo logger
  399.             }
  400.     }
  401.  
  402.     static void *procesarMensajes(void *arg) {
  403.         char *linea;
  404.         size_t len = 0;
  405.         ssize_t bytesLeidos;
  406.         ssize_t bytesEscritos;
  407.         int sockNewFileDescrpt = ((argthread_t *) arg)->clientFD;
  408.         pthread_t *thread = ((argthread_t *) arg)->thread;
  409.         FILE *mensajeCliente = fdopen(sockNewFileDescrpt, "r");
  410.  
  411.         // Registro del usuario
  412.         if (!pedirLogin(mensajeCliente, (argthread_t *) arg)) {
  413.             if (write(sockNewFileDescrpt, "fallo la conexion al sistema.\n", 30) < 0 ) {
  414.                 perror("ERROR --> No se pudo informar de error al cliente");
  415.                 // ToDo logger
  416.             }
  417.             fclose(mensajeCliente);
  418.             close(sockNewFileDescrpt);
  419.             kickearUsuario((argthread_t*) arg);
  420.             free(arg);
  421.             free(thread);
  422.             return NULL;    // Salgo del thread
  423.         }
  424.  
  425.         bytesEscritos = write(sockNewFileDescrpt, "conectado al servidor\n", 22);
  426.         string userCon(((argthread_t *) arg)->user);
  427.         userCon.erase(userCon.length()-1);
  428.         logger.loggearConexion(userCon);
  429.         cout << "\033[1m\033[32mSe conectó \033[1m\033[32m" << ((argthread_t *) arg)->user << "\033[0m";
  430.         mandarUsuarios(sockNewFileDescrpt);     // Mando lista de usuarios al cliente por unica vez
  431.  
  432.         while (true) {
  433.  
  434.             // SETEO RESTRICCION DE TIMEOUT PARA EL PEDIDO DE INSTRUCCION/MENSAJES
  435.             fd_set read_fds, write_fds, except_fds;
  436.             FD_ZERO(&read_fds);
  437.             FD_ZERO(&write_fds);
  438.             FD_ZERO(&except_fds);
  439.             FD_SET(sockNewFileDescrpt, &read_fds);
  440.             struct timeval timeout;
  441.  
  442.             timeout.tv_sec = 10;
  443.             timeout.tv_usec = 0;
  444.  
  445.             // Uso el select para esperar el heartbeat del cliente
  446.             if (int rv = select(sockNewFileDescrpt + 1, &read_fds, &write_fds, &except_fds, &timeout) == 1) {
  447.                 // Primer getline para recibir instruccion
  448.                 bytesLeidos = getline(&linea, &len, mensajeCliente);
  449.             }
  450.  
  451.             else if (rv == 0) {
  452.                 cout << "\033[1;31mSe perdió la conexión con " << ((argthread_t *) arg)->user << "\033[0m";
  453.                 string userDesc(((argthread_t *) arg)->user);
  454.                 userDesc.erase(userDesc.length()-1);
  455.                 logger.loggearDesconexionViolenta(userDesc);
  456.                 free(linea);
  457.                 linea = NULL;
  458.                 break;
  459.             }
  460.  
  461.             else{
  462.                 perror("ERROR --> select");
  463.                 free(linea);
  464.                 linea = NULL;
  465.                 break;
  466.             }
  467.  
  468.             if (bytesLeidos < 0) {
  469.                 string userDesc(((argthread_t *) arg)->user);
  470.                 userDesc.erase(userDesc.length()-1);
  471.                 logger.loggearDesconexionViolenta(userDesc);
  472.                 cout << "\033[1;31mSe desconectó MAL " << ((argthread_t *) arg)->user << "\033[0m";
  473.                 free(linea);
  474.                 break;
  475.             }
  476.  
  477.             //cout << "debug: Mensaje recibido del cliente: " << linea;
  478.  
  479.             // Opcion enviar mensaje
  480.             if (strcmp(linea, "/E/\n") == 0) {
  481.                 free(linea);
  482.                 linea = NULL;
  483.                 bytesLeidos = getline(&linea, &len, mensajeCliente);
  484.  
  485.                 // ENVIO MENSAJE
  486.                 if ( !enviarMensaje((argthread_t*) arg, linea, &bytesLeidos, false) )
  487.                     break;
  488.             }
  489.                 //si se tiene que mover
  490.             else if (strcmp(linea, "/M/\n") == 0) {
  491.                 free(linea);
  492.                 linea = NULL;
  493.                 bytesLeidos = getline(&linea, &len, mensajeCliente);
  494.  
  495.                 // ENVIO MENSAJE
  496.                 if ( !enviarMensaje((argthread_t*) arg, linea, &bytesLeidos, true) )
  497.                     break;
  498.             }
  499.  
  500.  
  501.  
  502.                 // Opcion recibir msjs
  503.             else if (strcmp(linea, "/R/\n") == 0) {
  504.                 free(linea);
  505.                 linea = NULL;
  506.                 recibirMensajes((argthread_t*) arg, &bytesEscritos, sockNewFileDescrpt);
  507.             }
  508.  
  509.                 // Desconecto al cliente desde el servidor
  510.             else if (strcmp(linea, "/D/\n") == 0) {
  511.                 free(linea);
  512.                 linea = NULL;
  513.                 string userDesc(((argthread_t *) arg)->user);
  514.                 userDesc.erase(userDesc.length()-1);
  515.                 logger.loggearDesconexionNormal(userDesc);
  516.                 cout << "\033[32mSe desconectó BIEN \033[32m" << ((argthread_t*) arg)->user << "\033[0m";
  517.                 break;
  518.             }
  519.  
  520.             else if (strcmp(linea, "/Z/\n") == 0) {
  521.                 if ((bytesEscritos = write(sockNewFileDescrpt, "/Z/\n", 4)) <= 0) {
  522.                     cout << "El cliente se desconecto del servidor1" << endl;
  523.                     break;
  524.                 }
  525.             }
  526.  
  527.             else if (strcmp(linea, "/H/\n") == 0) {
  528.                 free(linea);
  529.                 linea = NULL;
  530.             }
  531.  
  532.             else {
  533.                 cout << "El cliente se desconecto del servidor2" << endl;
  534.                 free(linea);
  535.                 linea = NULL;
  536.                 break;
  537.             }
  538.  
  539.             free(linea);
  540.             linea = NULL;
  541.  
  542.         }
  543.  
  544.         close(sockNewFileDescrpt);
  545.         kickearUsuario((argthread_t*) arg);
  546.         free(arg);
  547.         free(thread);
  548.         fclose(mensajeCliente);
  549.         return NULL;
  550.     }
  551.  
  552. public:
  553.     Servidor(unsigned short int numPuerto, string nombreArchivo) {
  554.  
  555.         nombreArchivoCsv = nombreArchivo;
  556.         bzero(&attr, sizeof(attr));
  557.  
  558.         pthread_attr_init(&attr);
  559.         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  560.         mutex_mensajes = PTHREAD_MUTEX_INITIALIZER;
  561.         mutex_login = PTHREAD_MUTEX_INITIALIZER;
  562.  
  563.  
  564.         // Creo thread de CONTROL
  565.         if (pthread_create(&threadControl, &attr, controlInput, &serverOn) != 0) {
  566.             cerr << "ERROR --> No se pudo crear thread de control" << endl;
  567.             pthread_attr_destroy(&attr);
  568.             throw NoSePudoCrearServidorException();
  569.         }
  570.  
  571.  
  572.         bzero(&serv_addr, sizeof(serv_addr));   // Inicializo structs
  573.         bzero(&cli_addr, sizeof(cli_addr));
  574.  
  575.         fileDescrpt = socket(AF_INET, SOCK_STREAM, 0);
  576.  
  577.         if (fileDescrpt < 0) {
  578.             logger.error("no se pudo abrir el socket");
  579.             cerr << "ERROR --> No se pudo abrir socket" << endl;
  580.             pthread_attr_destroy(&attr);
  581.             throw NoSePudoCrearServidorException();
  582.         }
  583.  
  584.         serv_addr.sin_family = AF_INET;
  585.         serv_addr.sin_addr.s_addr = INADDR_ANY;
  586.         serv_addr.sin_port = htons(numPuerto);  // --> convierte de hostbyte order a network byte order
  587.  
  588.         // Aviso al SO que asocie el programa al socket creado
  589.         if (bind(fileDescrpt, (const sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
  590.             logger.error("no se pudo crear servidor");
  591.             close(fileDescrpt);
  592.             pthread_attr_destroy(&attr);
  593.             throw NoSePudoCrearServidorException();
  594.         }
  595.  
  596.         // Comienza a escuchar a los clientes que se quieren conectar y los va encolando
  597.         if (listen(fileDescrpt, MAX_CLIENTS) < 0) {
  598.             logger.error("se alcanzo la cant maxima de clientes");
  599.             cerr << "ERROR --> Falla en listen" << endl;
  600.             close(fileDescrpt);
  601.             pthread_attr_destroy(&attr);
  602.             throw NoSePudoCrearServidorException();
  603.         }
  604.  
  605.         serverOn = true;
  606.         cargarUsuarios(nombreArchivo);
  607.         logger.inicializoServer();
  608.  
  609.     }
  610.  
  611.     void aceptarClientes() {
  612.  
  613.         while (serverOn) {
  614.             int newFileDescrpt = accept(fileDescrpt, (sockaddr *) &cli_addr, &pesoCli_adrr);
  615.             if (newFileDescrpt < 0) {
  616.                 // cerr << "ERROR --> No se pudo aceptar cliente" << endl;
  617.                 // ToDo logger
  618.                 continue;
  619.             }
  620.  
  621.  
  622.             argthread_t *arg = (argthread_t *) malloc(sizeof(argthread_t));
  623.  
  624.             if (!arg) {
  625.                 close(newFileDescrpt);  // rechazo cliente
  626.                 cerr << "ERROR --> Falta memoria para cliente" << endl;
  627.                 continue;
  628.             }
  629.  
  630.             pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t));
  631.  
  632.             if (!thread) {
  633.                 close(newFileDescrpt); // rechazo cliente
  634.                 cerr << "ERROR --> Falta memoria para thread de cliente" << endl;
  635.                 continue;
  636.             }
  637.  
  638.             arg->clientFD = newFileDescrpt;
  639.             arg->thread = thread;
  640.             arg->user = NULL;
  641.             arg->clave = NULL;
  642.             conectados.push_back(arg);
  643.             if (pthread_create(thread, &attr, procesarMensajes, arg) != 0) {
  644.                 cerr << "ERROR --> Creación de thread fallida" << endl;
  645.                 conectados.pop_back();
  646.                 close(newFileDescrpt);      // Rechazar este cliente
  647.                 free(thread);
  648.                 free(arg);
  649.             }
  650.  
  651.  
  652.         }
  653.         logger.cierroServer();
  654.         logger.cerrarLog();
  655.     }
  656. };
  657.  
  658. vector<argthread_t*> Servidor::conectados;
  659. unordered_map<string, string> Servidor::usuarios;
  660. int Servidor::fileDescrpt;
  661. vector<Mensaje> Servidor::mensajes;
  662. pthread_mutex_t Servidor::mutex_mensajes;
  663. pthread_mutex_t Servidor::mutex_login;
  664. Log Servidor::logger(100);
  665. Personaje Servidor::personaje;
  666.  
  667. int main(int argc, char** argv) {
  668.  
  669.  
  670.     if (argc < 3) {
  671.         fprintf(stderr, "Modo de Uso: %s <archivo-usuarios> <n° puerto>\n", argv[0]);
  672.         exit(EXIT_SUCCESS);
  673.     }
  674.  
  675.     unsigned short int numPuerto = (unsigned short) strtoull(argv[2], NULL, 0);
  676.  
  677.     Servidor server = Servidor(numPuerto, argv[1]);
  678.     server.aceptarClientes();
  679.     return 0;
  680. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement