TCP Socket - C Language
|
00001 00011 #include <stdio.h> 00012 #include <unistd.h> 00013 #include <signal.h> 00014 00015 #include "pool.h" 00016 #include "comm.h" 00017 #include "errore.h" 00018 00022 #define MAXSRVSLEEP 128 00023 00025 volatile sig_atomic_t quitflag; 00026 00028 void *client_comm(void * sk); 00029 void gestore(int sig); 00030 00032 int main(int argc,char* argv[]){ 00033 int nsec; 00034 int cln_sk; 00035 th_pool * pool; 00036 sigset_t poolset; 00037 sigset_t set; 00038 char * service = "12100"; 00039 comm * srvComm = NULL; 00040 struct sigaction action; 00041 quitflag = 0; 00042 00043 /* ========= Gestione dei segnali ========= */ 00044 /* Blocco i segnali */ 00045 if (sigfillset(&set) == -1){ 00046 sys_err(__FILE__,__LINE__,"Server: error sigfillset: "); 00047 return EXIT_FAILURE; 00048 } 00049 00050 if (pthread_sigmask(SIG_SETMASK, &set, NULL) != 0) { 00051 sys_err(__FILE__,__LINE__, 00052 "Server: pthread_sigmask error 'sigsetmask': "); 00053 return EXIT_FAILURE; 00054 } 00055 00056 /* Installo il nuovo gestore */ 00057 memset(&action, 0, sizeof(action)); 00058 if (sigemptyset(&action.sa_mask) == -1){ 00059 sys_err(__FILE__,__LINE__,"Server: error sigemptyset: "); 00060 return EXIT_FAILURE; 00061 } 00062 00063 /* Ignoro il SIGPIPE */ 00064 action.sa_handler = SIG_IGN; 00065 if (sigaction(SIGPIPE, &action, NULL) == -1) { 00066 sys_err(__FILE__,__LINE__, "Server: sigaction error 'SIGPIPE': "); 00067 exit(EXIT_FAILURE); 00068 } 00069 action.sa_handler = gestore; 00070 action.sa_flags = 0; 00071 00072 /* Definisco i segnali che voglio gestire */ 00073 if (sigaction(SIGINT, &action, NULL) < 0){ 00074 sys_err(__FILE__,__LINE__,"Server: sigaction error 'SIGINT': "); 00075 return EXIT_FAILURE; 00076 } 00077 00078 if (sigaction(SIGTERM, &action, NULL) < 0){ 00079 sys_err(__FILE__,__LINE__,"Server: sigaction error 'SIGTERM': "); 00080 return EXIT_FAILURE;; 00081 } 00082 00083 /* Installo la nuova maschera dei segnali */ 00084 if (pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL) != 0) { 00085 sys_err(__FILE__,__LINE__, 00086 "Server: pthread_sigmask error 'sigsetmask': "); 00087 return EXIT_FAILURE; 00088 } 00089 00090 /* Questa maschera per il pool che ignora tutti i segnali */ 00091 if (sigfillset(&poolset) == -1){ 00092 sys_err(__FILE__,__LINE__,"Server: error sigfillset: "); 00093 exit(errno); 00094 } 00095 00096 /* Creo una socket di comunicazione */ 00097 if (!(srvComm = newServerChannel(service))){ 00098 sys_err(__FILE__,__LINE__,"Server: createServerChannel: "); 00099 exit(errno); 00100 } 00101 00102 /* Inizializzo un pool di thread di dimensione 5 e con 00103 * un numero massimo di job in attesa nella coda di 10 */ 00104 pool = poolInit(5, 10, &poolset); 00105 00106 while (!quitflag){ 00107 /* Pongo il server in attesa di nuove connessioni */ 00108 if ((cln_sk = acceptConnection(srvComm)) > 0){ 00109 /* Sottomissione job al pool con riprova (lenta) */ 00110 for (nsec = 1; nsec<=MAXSRVSLEEP && poolDispatcher(pool, client_comm, &cln_sk)==-5; nsec<<=1) 00111 if (nsec<=MAXSRVSLEEP/2) sleep(nsec); 00112 } 00113 /* TODO Manca la gestione degli errori */ 00114 } 00115 00116 /* Arresto il pool di threads e libero le risorse */ 00117 poolDestroy(pool); 00118 /* Chiudo la socket di comunicazione */ 00119 closeServerSocket(srvComm); 00120 return 0; 00121 } 00122 00123 void *client_comm(void * sk){ 00124 int sk_cl; 00125 message_t msg; 00126 int recive_val = 1, sent_val = 1, quit = 0; 00127 00128 sk_cl = *(int *)sk; 00129 msg.buffer = NULL; 00130 00131 while ((recive_val>0) && (sent_val>0) && (quit!=1)){ 00132 /* Ricevo un messaggio */ 00133 if ((recive_val = receiveMessage(sk_cl, &msg)) > 1){ 00134 /* Controllo il tipo di messaggio ricevuto */ 00135 switch(msg.type){ 00136 case MSG_EXIT: 00137 quit = 1; 00138 msg.length = 0; 00139 if (msg.buffer) free(msg.buffer); 00140 msg.buffer = NULL; 00141 msg.type = MSG_OK; 00142 break; 00143 case MSG_PRINT: 00144 if (msg.buffer){ 00145 printf ("Mgs: %s\n",msg.buffer); 00146 free(msg.buffer); 00147 } 00148 msg.length = 0; 00149 msg.buffer = NULL; 00150 msg.type = MSG_OK; 00151 break; 00152 } 00153 /* Invio il messaggio di risposta */ 00154 sent_val = sendMessage(sk_cl, &msg); 00155 } 00156 } 00157 00158 printf("Server: Comunicazione con il client chiusa\n"); 00159 /* Chiudo la socket di comunicazione */ 00160 closeConnection(sk_cl); 00161 return 0; 00162 } 00163 00172 void gestore(int sig) { 00173 switch (sig) { 00174 case SIGTERM: 00175 write(2, "server: signal 15 detected\n", 27); 00176 quitflag = 1; 00177 break; 00178 case SIGINT: 00179 write(2, "server: signal 2 detected\n", 26); 00180 quitflag = 1; 00181 break; 00182 } 00183 }