|
TCP Socket - C Language
|
#include <stdio.h>#include <unistd.h>#include <signal.h>#include "pool.h"#include "commSSL.h"#include "errore.h"Vai al codice sorgente di questo file.
Definizioni | |
| #define | MAXSRVSLEEP 128 |
Funzioni | |
| void * | client_comm (void *client_info) |
| void | gestore (int sig) |
| int | main (int argc, char *argv[]) |
Variabili | |
| volatile sig_atomic_t | quitflag |
This program is free software; you can redistribuite it and/or modify it under the terms of the GNU/General Pubblic License as published the Free software Foundation; either version 2 of the License, or (at your opinion) any later version.
Definizione nel file serverSSL.c.
| #define MAXSRVSLEEP 128 |
Tempo di ritardo per l'inserimento di un nuovo job nel pool di thread nel caso di coda dei lavori piena: 128 => 2 minuti.
Definizione alla linea 23 del file serverSSL.c.
| void* client_comm | ( | void * | client_info | ) |
Funzione che si occupa della reale comunicazione con il client
| void gestore | ( | int | sig | ) |
Il mio gestore dei segnali
Stampa a monitor il codice del segnale ricevuto se questo e' SIGTERM o SIGINT e mette quitflag a 1, altrimenti se e' un SIGPIPE non fa nulla.
| sig | codice del segnale ricevuto |
| int main | ( | int | argc, |
| char * | argv[] | ||
| ) |
Main di esempio del server
Definizione alla linea 33 del file serverSSL.c.
{
int nsec;
char * service = "12100";
srvSkSSL * server = NULL;
cli_conn * client = NULL;
th_pool * pool;
sigset_t poolset;
sigset_t set;
struct sigaction action;
quitflag = 0;
/* ========= Gestione dei segnali ========= */
/* Blocco i segnali */
if (sigfillset(&set) == -1){
sys_err(__FILE__,__LINE__,"Server: error sigfillset");
return EXIT_FAILURE;
}
if (pthread_sigmask(SIG_SETMASK, &set, NULL) != 0) {
sys_err(__FILE__,__LINE__,
"Server: pthread_sigmask error 'sigsetmask'");
return EXIT_FAILURE;
}
/* Installo il nuovo gestore */
memset(&action, 0, sizeof(action));
if (sigemptyset(&action.sa_mask) == -1){
sys_err(__FILE__,__LINE__,"Server: error sigemptyset");
return EXIT_FAILURE;
}
/* Ignoro il SIGPIPE */
action.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &action, NULL) == -1) {
sys_err(__FILE__,__LINE__, "Server: sigaction error 'SIGPIPE'");
exit(EXIT_FAILURE);
}
action.sa_handler = gestore;
action.sa_flags = 0;
/* Definisco i segnali che voglio gestire */
if (sigaction(SIGINT, &action, NULL) < 0){
sys_err(__FILE__,__LINE__,"Server: sigaction error 'SIGINT'");
return EXIT_FAILURE;
}
if (sigaction(SIGTERM, &action, NULL) < 0){
sys_err(__FILE__,__LINE__,"Server: sigaction error 'SIGTERM'");
return EXIT_FAILURE;;
}
/* Installo la nuova maschera dei segnali */
if (pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL) != 0) {
sys_err(__FILE__,__LINE__,
"Server: pthread_sigmask error 'sigsetmask'");
return EXIT_FAILURE;
}
/* Questa maschera per il pool che ignora tutti i segnali */
if (sigfillset(&poolset) == -1){
sys_err(__FILE__,__LINE__,"Server: error sigfillset");
exit(errno);
}
/* Creo una socket di comunicazione */
if ((server = newSSLServerChannel(service)) == NULL){
sys_err(__FILE__,__LINE__,"Server: createServerChannel");
exit(errno);
}
/* Inizializzo un pool di thread di dimensione 5 e con
* un numero massimo di job in attesa nella coda di 10 */
pool = poolInit(5, 10, &poolset);
while (!quitflag){
/* Pongo il server in attesa di nuove connessioni */
if ((client = acceptSSLConnection(server)) != NULL){
/* Sottomissione job al pool con riprova (lenta) */
for (nsec = 1; nsec<=MAXSRVSLEEP && poolDispatcher(pool, client_comm, client)==-5; nsec<<=1)
if (nsec<=MAXSRVSLEEP/2) sleep(nsec);
}
/* TODO Manca la gestione degli errori */
}
/* Arresto il pool di threads e libero le risorse */
poolDestroy(pool);
/* Chiudo la socket di comunicazione */
closeSSLServerSocket(server);
unloadSSL();
return 0;
}
| volatile sig_atomic_t quitflag |
Variabile atomica per la terminazione del server
Definizione alla linea 26 del file serverSSL.c.