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