/** @file * \brief Implementación del servidor * \author Imanol Barba Sabariego * \date 13/06/2013 * * En este fichero se implementa un servidor TCP/IP usando las clases Socket y Server. */ #include "server.h" #include #include #include //!Instancia de la clase Server /*! Esta variable contiene la instancia de la clase Server que aquí se usa e inicializa. _Se trata de una variable global para poder así usarla en las funciones que reciban signals del SO._ */ Server *serv; void killThread(thread_args *t_arg) { (t_arg->s)->Close(); pthread_mutex_lock(t_arg->mutex); t_arg->serv->setNWorkers(t_arg->serv->getNWorkers()-1); cout << "TCP: Worker " << t_arg->id << ": connection terminated" << endl; pthread_mutex_unlock(t_arg->mutex); pthread_cond_signal(t_arg->condition); t_arg->serv->getStartedThreads()->remove(t_arg->thread); t_arg->serv->getStoppedThreads()->push_back(t_arg->thread); if(t_arg->s != 0) { delete t_arg->s; t_arg->s = 0; } if(t_arg != 0) { delete t_arg; t_arg = 0; } pthread_exit(NULL); } void *WorkerThread(void* args) { struct thread_args *t_arg = (struct thread_args*)args; try { while(true) { string message; *(t_arg->s) >> message; if(message == "exit") { *(t_arg->s) << "OK"; break; } else if(message == "test") { string data; *(t_arg->s) >> data; cout << "TCP: Received " << data.length() << " bytes" << endl; *(t_arg->s) << "ACK"; } else { cout << "TCP: Worker " << t_arg->id << " received: " << message << endl; string send = "You said: "; send += message; *(t_arg->s) << send; } } } catch(SocketException& e) { cout << e.description() << endl; cout << "TCP: Client closed the connection unexpectedly" << endl; } killThread(t_arg); } //! Método de detención del servidor /*! Este método detiene el servidor al recibir el signal SIGINT del SO. */ void stopServer(int signal/*!requestExit(); } void processText(string *str) { for(int i = 0; i < str->length(); i++) { if((*str)[i] == 32 || (*str)[i] == 10 || (*str)[i] == 11) { str->erase(i--,1); } } } bool readConf(string *ip, int *port) { *ip = ""; *port = 0; ifstream confFile; confFile.open(CONFFILE); if(!confFile.is_open()) { cout << "TCP: Error opening configuration file" << endl; return false; } string parameter; while(true) { getline(confFile, parameter, '='); processText(¶meter); if(confFile.eof()) { break; } if(parameter == "bind-ip") { confFile >> *ip; } else if(parameter == "port") { confFile >> *port; } } confFile.close(); if(*ip == "" || *port == 0) { return false; } return true; } //! Método principal del servidor /*! Lee la configuración usando readConf() y incializa el servidor. */ int main() { stringstream sstream; string ip; int port; serv = new Server(); signal(SIGINT, stopServer); if(!readConf(&ip,&port)) { cout << "TCP: Configuration couldn't be loaded" << endl; return -1; } serv->startServer(ip,port); delete serv; return 0; } /* TO-DO * * Request nick * map with sockets/nicks * spawn a messagesend thread */