Código:
#define NUM_THREADS 5
//−−− S e r v i d o r −−−−−−−−−− −−−−−−−−−−−−−−−−−−−−−−−−−−
// R e a l i z a r e l p r o c e d i m i e n t o s e r v i c i o −−−−−−−−−−−−−−−
void *Servidor(void *threadarg){
char buf[1024];
char reply[1024];
int sd, bytes;
const char* HTMLecho="Esto solo es el mensaje de mi servidor SSL multihilo";
// Estructura donde se guardan los parametros de los threads
struct thread_data *my_data;
int taskid;
// Parser de los datos de la estructura a variables
my_data=(struct thread_data*)threadarg;
taskid=my_data->thread_id;
SSL *ssl=my_data->message;
HTMLecho=my_data->reto;
printf("Inicia Servidor\n");
if(SSL_accept(ssl)==FAIL){
printf("Hubo un error en el SSL accept\n");
ERR_print_errors_fp(stderr);
} else{
printf("SSL accept fue exitoso\n");
//MostrarCertificados(ssl);
bytes=SSL_read(ssl,buf,sizeof(buf));
if(bytes>0){
buf[bytes]=0;
printf("Mensaje cliente [%d]: %s\n", taskid,buf);
sprintf(reply,HTMLecho,buf);
sleep (30);
//SSL_write(ssl,reply,strlen(reply));
SSL_write(ssl,reply,20);
}
else
ERR_print_errors_fp(stderr);
}
sd=SSL_get_fd(ssl);
SSL_free(ssl);
close(sd);
}
//−−− Main −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
// Se e n c a r g a de c r e a r e l s e r v i d o r
int main(int count, char *strings[]){
//Arreglo de hilos
pthread_t threads[NUM_THREADS];
struct thread_data thread_data_array[NUM_THREADS];
int t=0;
int rc;
SSL_CTX *ctx;
int server;
char *portnum;
SSL_library_init();
if(count!= 2){
printf("Uso : %s <portnum>\n", strings[0]);
exit(0);
}
//Genero el reto
printf("Generando reto...\n");
/* Longitud del reto */
unsigned short int length = 20;
char reto[20];
/* Seed number for rand() */
srand((unsigned int) time(0) + getpid());
/* ASCII characters 33 to 126 */
int aux=0;
while(length--) {
reto[aux]=putchar(rand() % 94 + 33);
srand(rand());
aux++;
}
reto[aux]='\0';
printf("\n");
//imprimirReto(reto);
const char* HTMLecho;
HTMLecho=reto;
portnum = strings [1];
ctx=IniciarCTXServidor();
CargarCertificados(ctx,"/home/xabi/Escritorio/examples/ssl/proyecto/certificados/servidor/server.crt","/home/xabi/Escritorio/examples/ssl/proyecto/certificados/servidor/server.key");//Certificado y clave
server=CrearSocket(atoi(portnum));
printf("Esperando por conexiones[%d]\n", server);
printf("Inicia a aceptar conexiones\n");
while(1){
struct sockaddr_in addr;
SSL *ssl;
int len=sizeof(addr);
int client=accept(server,(struct sockaddr*)&addr,&len);
printf("Connection: %d %d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
ssl=SSL_new(ctx);
// Se crea contexto
SSL_set_fd(ssl,client);
t++;
// Se da numero de pthread
thread_data_array[t].thread_id=t;
// Se le da el id del thread al thread
thread_data_array[t].message=ssl;
// Se le da el asigna el contexto de la conexion al thread
thread_data_array[t].reto=(char *)HTMLecho;
rc=pthread_create(&threads[t],NULL,Servidor,(void *)&thread_data_array[t]);
// Se crea el hilo y se le manda la estructura llenada previamente
if(t==NUM_THREADS){ //DUDA!!!!!!!!!
sleep(5);
t=0;
}
}
close(server);
SSL_CTX_free(ctx);
}
Como veis para cada peticion que llega crea un hilo que atiende esta petición y tengo definido un máximo de 5 peticiones. De esta forma funcionaba, pero después de la 5 petcion , al llegar la 6 lógicaente da un error de segmentacion. Así que decidi poner, si llega a la 5 petición pongo el contador a 0 y que siga creando hilos, perono estoy seguro de que este bien ya que vuelvo a crear un hilo con id=0 por ejemplo igual que el otro hilo id=0 que no se si acabo o no y supongo que puede darme problemas de concurrecia en el futuro.
Alguna idea de como mejorar esto? Gracias