TCP Socket - C Language
|
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include "pool.h"
#include "comm.h"
#include "errore.h"
Vai al codice sorgente di questo file.
Definizioni | |
#define | MAXSRVSLEEP 128 |
Funzioni | |
void * | client_comm (void *sk) |
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 server.c.
#define MAXSRVSLEEP 128 |
void * client_comm | ( | void * | sk | ) |
Funzione che si occupa della reale comunicazione con il client
Definizione alla linea 123 del file server.c.
{ int sk_cl; message_t msg; int recive_val = 1, sent_val = 1, quit = 0; sk_cl = *(int *)sk; msg.buffer = NULL; while ((recive_val>0) && (sent_val>0) && (quit!=1)){ /* Ricevo un messaggio */ if ((recive_val = receiveMessage(sk_cl, &msg)) > 1){ /* Controllo il tipo di messaggio ricevuto */ switch(msg.type){ case MSG_EXIT: quit = 1; msg.length = 0; if (msg.buffer) free(msg.buffer); msg.buffer = NULL; msg.type = MSG_OK; break; case MSG_PRINT: if (msg.buffer){ printf ("Mgs: %s\n",msg.buffer); free(msg.buffer); } msg.length = 0; msg.buffer = NULL; msg.type = MSG_OK; break; } /* Invio il messaggio di risposta */ sent_val = sendMessage(sk_cl, &msg); } } printf("Server: Comunicazione con il client chiusa\n"); /* Chiudo la socket di comunicazione */ closeConnection(sk_cl); return 0; }
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 32 del file server.c.
{ int nsec; int cln_sk; th_pool * pool; sigset_t poolset; sigset_t set; char * service = "12100"; comm * srvComm = NULL; 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 (!(srvComm = newServerChannel(service))){ 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 ((cln_sk = acceptConnection(srvComm)) > 0){ /* Sottomissione job al pool con riprova (lenta) */ for (nsec = 1; nsec<=MAXSRVSLEEP && poolDispatcher(pool, client_comm, &cln_sk)==-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 */ closeServerSocket(srvComm); return 0; }