Ciao a tutti ho un problema, o meglio vorrei un chiarimento su server con un thread che gestisce le connessioni.
La mia classe server è fatta così:
server.h
server.cppcodice:class Server { public: /** *\brief Costruttore della classe */ Server (); /** *\brief Distruttore della classe */ virtual ~Server(); /** *\brief Metodo che fa partire il server */ void Start(); /** *\brief Metodo che ferma il server */ void Stop(); /** *\brief Metodo che imposta il segnale di spegnimento del server e attende il completamento delle operazioni */ void WaitForCompletation(); private: /** *\brief Metodo che implementa la routine del server e lo pone in ascolto sulla porta specificata nel file di configurazione */ void Run (); /** *\brief Metodo che viene richiamato nel caso di una nuova connessione sul server principale e gestisce le richieste. */ void serviceRoutine(Socket * sock); private: Centrale * centrale; // unsigned char pacchetto[512]; // unsigned char recvBuffer[512]; Database * db_epro; Parametri * param; Logger * log; Socket serversock; thread mainthread; thread thread_serventi[10]; int n_thread; bool thread_stop; }; #endif // SERVER_H
ora il mio dubbio è:codice:Server::Server() { #if (DEBUGSERVER >=2) cout<<"Chiamato costruttore della classe server\n"; #endif Server::param = new Parametri(FILEPARAM); #if (DEBUGSERVERs >=2) cout<<"Chiamato new Parametri\n"; #endif Server::db_epro = new Database(param->getParametro(DATABASE), //Nome db param->getParametro(IP_DB), //IP del db param->getParametro(PORT_DB), //Porta del db param->getParametro(USER_DB), //Nome utente param->getParametro(PASSWD_DB)); //Password di accesso Server::log = new Logger(param->getParametro(FILELOG),param->getParametro(PATHLOG)); n_thread = 0; } Server::~Server() { cout<<"Distruttore del server\n"; delete param; delete db_epro; delete log; } void Server::WaitForCompletation() { Server::Stop(); for (int i = 0; i<n_thread; i++) { thread_serventi[i].join(); } mainthread.join(); } void Server::Stop() { thread_stop = true; } void Server::Start() { for(int i = 0 ; i< n_thread; i++) { thread_serventi[i].join(); } mainthread = std::move(std::thread(&Server::Run,this)); thread_stop = false; } void Server::Run() { Socket serversock; Socket new_sock; stringstream Stream; if(!serversock.create()) { throw SocketException ("Could not create client socket."); return; } cout<< "Creazione avvenuta con successo\n"; if(!serversock.bind(atol(param->getParametro(PORTASCOLTO).c_str()))) { throw SocketException ( "Could not bind to port." ); return; } cout<< "Binding OK!!!\n"; if ( ! serversock.listen() ) { throw SocketException ( "Could not listen to socket." ); } cout<< "Listening OK!!!\n"; serversock.set_non_blocking(true); while(!thread_stop) { serversock.accept(new_sock); if (new_sock.is_valid()) { cout<<"Ricevuta connessione\n"; thread_serventi[n_thread] = move(thread(&Server::serviceRoutine,this,&new_sock)); n_thread++; } } cout<<"Fermato thread principale del server\n"; return; } void Server::serviceRoutine(Socket * sock) { unsigned char recvBuff[512]; unsigned char pacchettoinv[512]; Centrale * centrale = NULL; int start = 0; int len = 0; short crc = 0XFFFF; long codice = 0; stringstream Stream; int nelem; int n; string query; PGresult * res; sock->set_non_blocking(false); while(!thread_stop) { memset(recvBuff,'\0',512); start = 0; ///Ricezione del pacchetto n = sock->recv(recvBuff); cout<<"Ricevuto pacchetto\n"; ///Trovo il byte iniziale in caso il buffer sia sporco while((recvBuff[start]!= 0x0A) && (start <n)) { start++; } if (n<=0) { break;; } else { printf("Il valore 0x0A si trova in posizione %d\n", start); len = recvBuff[start+1]; crc = (recvBuff[start+len+3]&0xFF)+((recvBuff[start+len+4]&0xFF)<<8); ///Controllo che il pacchetto sia corretto. if ((crc&0xFFFF) == Crc_16(&recvBuff[start],len+3)) { ///Individuo il tipo di pacchetto e mi comporto di conseguenza switch(recvBuff[start+2]) { case 0x01:///Pacchetto iniziale { cout<<"Identificato pacchetto iniziale\n"; memset(pacchettoinv,'\0',512); codice = (((recvBuff[start+3]>>4)&0x0F)*100000)+ ((recvBuff[start+3]&0x0F)*10000) + (((recvBuff[start+4]>>4)&0x0F)*1000) + ((recvBuff[start+4]&0x0F)*100) + (((recvBuff[start+5]>>4)&0x0F)*10) + ((recvBuff[start+5]&0x0F)*1) ; Stream<<codice; query = "SELECT ce_modalita_telegestione FROM centrali WHERE ce_id = '"; query.append(Stream.str()); query.append("';"); res = db_epro->eseguiQuery(query,1); if ((strcmp(PQgetvalue(res,0,0),"TECNOOUT")==0)||(strcmp(PQgetvalue(res,0,0),"TECNO OUT")==0)) { centrale = new xxx(codice); //centrale->Start(); }///Qui si introdurranno altre centrali else { cout<<"Centrale non valida\n"; n_thread--; return; } pacchettoinv[0] = 0x0A; pacchettoinv[1] = 0x00; pacchettoinv[2] = 0x09; crc = Crc_16(pacchettoinv,3); pacchettoinv[3] = crc & 0xFF; pacchettoinv[4] = (crc >> 8) & 0xFF; sock->send(pacchettoinv,5); break; } case 0x03: ///Richiesta stato della centrale { cout<<"Identificato pacchetto richiesta stato centrale\n"; memset(pacchettoinv,'\0',512); pacchettoinv[0] = 0x0A; pacchettoinv[1] = 0x01; pacchettoinv[2] = 0x06; pacchettoinv[3] = centrale->getStatoCentrale(); crc= Crc_16(pacchettoinv,4); pacchettoinv[4] = crc & 0xFF; pacchettoinv[5] = (crc >> 8) & 0xFF; sock->send(pacchettoinv,6); break; } case 0x04: ///Richiesta stato della zona { cout<<"Identificato pacchetto richiesta stato zona\n"; memset(pacchettoinv,'\0',512); nelem=(((recvBuff[start+3]>>4)&0x0F)*1000) + ((recvBuff[start+3]&0x0F)*100) + (((recvBuff[start+4]>>4)&0x0F)*10) + ((recvBuff[start+4]&0x0F)*1); pacchettoinv[0] = 0x0A; pacchettoinv[1] = 0x01; pacchettoinv[2] = 0x07; pacchettoinv[3] = centrale->getStatoZone(nelem); crc= Crc_16(pacchettoinv,4); pacchettoinv[4] = crc & 0xFF; pacchettoinv[5] = (crc >> 8) & 0xFF; sock->send(pacchettoinv,6); break; } case 0x05: ///Richiesta stato della partizione { cout<<"Identificato pacchetto richiesta stato partizione\n"; memset(pacchettoinv,'\0',512); nelem=(((recvBuff[start+3]>>4)&0x0F)*10) + ((recvBuff[start+3]&0x0F)*1) ; pacchettoinv[0] = 0x0A; pacchettoinv[1] = 0x01; pacchettoinv[2] = 0x08; pacchettoinv[3] = centrale->getStatoPartizioni(nelem); crc= Crc_16(pacchettoinv,4); pacchettoinv[4] = crc & 0xFF; pacchettoinv[5] = (crc >> 8) & 0xFF; sock->send(pacchettoinv,6); break; } } } else { cout<<"Errore nel CRC\n"; } } } if (centrale != NULL) { //centrale->WaitForCompletation(); delete centrale; cout<<"Qui ci arrivo\n"; } sock->chiudi(); n_thread--; return; }
nel metodo Run è giusto creare un array di thread e attivarli mano a mano che ricevo connessioni
o sarebbe meglio avere un solo thread e farlo detached?
se si come?
Attualmente quando chiudo il programma ho un errore e credo sia dovuto al fatto di avere dei thread in sospeso.

Rispondi quotando
... Troppa poca programmazione all'università
