/** @file * \brief Fichero de implementación de la clase Server * \author Imanol Barba Sabariego * \date 13/06/2013 * * En este fichero se implementan los métodos de la clase Server definidos en server.h */ #include "server.h" using namespace std; int Server::getNWorkers() { return nWorkers; } void Server::setNWorkers(int n) { nWorkers = n; } list* Server::getStartedThreads() { return &startedThreads; } list* Server::getStoppedThreads() { return &stoppedThreads; } void Server::freeRAM(list *threadList) { int count = 0; for(list::iterator it = threadList->begin(); it != threadList->end(); it++) { if(*it != 0) { delete *it; *it = 0; } count++; } threadList->clear(); cout << "TCP: " << count << " Threads freed" << endl; } void Server::requestExit() { cout << "TCP: Exiting!" << endl; shutdownServer = true; ss.Close(); } void Server::startServer(string i, int p) { Socket ss; ss.loadKeys(PUBLICKEY,PRIVATEKEY); string ip = i; int port = p; signal(SIGPIPE, SIG_IGN); try { int optval = 1; ss.Create(); setsockopt(ss.getSock(),SOL_SOCKET,SO_REUSEADDR,&optval,sizeof optval); ss.Bind(ip,port); } catch(SocketException& e) { cout << e.description() << endl; return; } pthread_mutex_t m_mutex; pthread_mutex_init(&m_mutex,0); pthread_cond_t condition; pthread_cond_init(&condition,0); ss.Listen(N); while(!shutdownServer) { pthread_mutex_lock(&m_mutex); while(nWorkers >= N) { cout << "TCP: Server sleeping" << endl; pthread_cond_wait(&condition,&m_mutex); } freeRAM(&stoppedThreads); pthread_mutex_unlock(&m_mutex); Socket *cs = new Socket(); try { ss.Accept(*cs); } catch(SocketException& e) { break; } pthread_mutex_lock(&m_mutex); cs->setKeys(ss.getPublicKey(), ss.getPrivateKey(), ss.getAESKey(), ss.getAESIV()); if(!cs->sendPublicKey() || !cs->receivePublicKey()) { cs->Close(); if(cs != 0) { delete cs; cs = 0; } pthread_mutex_unlock(&m_mutex); continue; } cs->sendAES(); cs->recvAES(); thread_args *t_args = new thread_args; pthread_t *thread = new pthread_t; t_args->mutex = &m_mutex; t_args->condition = &condition; t_args->id = workerID++; t_args->s = cs; t_args->serv = this; t_args->thread = thread; startedThreads.push_back(thread); cout << "TCP: Client connected" << endl; nWorkers++; pthread_create(thread,NULL,WorkerThread,(void *)t_args); pthread_mutex_unlock(&m_mutex); } cout << "TCP: Running Threads:" << endl; freeRAM(&startedThreads); cout << "TCP: Stopped Threads:" << endl; freeRAM(&stoppedThreads); }