Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Problemas con hilos y socket

Estas en el tema de Problemas con hilos y socket en el foro de C/C++ en Foros del Web. hola necesitaba una ayuda con mi código porque no se donde me esta fallando me da dos errores: 1-si me conecto al servidor desde el ...
  #1 (permalink)  
Antiguo 18/12/2012, 09:51
 
Fecha de Ingreso: diciembre-2011
Mensajes: 17
Antigüedad: 12 años, 4 meses
Puntos: 0
Problemas con hilos y socket

hola necesitaba una ayuda con mi código porque no se donde me esta fallando me da dos errores:
1-si me conecto al servidor desde el navegador una sola vez sin recargar la pagina me sale un error de "violación de segmento ('core' generado)".
2-si recargo la pagina mas de 4 veces se sale del programa sin mas, sin pasar por ningún control de error.

necesito ayuda lo antes posible que tengo que entregar el proyecto a final de mes!

Desde ya muchas gracias!

Aquí te dejo parte del código:


*****Haciendo mas pruebas he comprobado que mi problema viene por no cerrar los hilos correctamente, pero es que en el if donde comprueba que se pide una pagina html no se porque no me lo cierra y si quito esa parte del código o lo obligo a cerrar todos los hilos no me da ninguna error!

#includes....

#define BACKLOG 5 // El número de conexiones permitidas
#define TAMANHO_BUFFER 1024

//*************************** CLASE THREAD ************************************

class Thread
{
public:
Thread() {};
int Start(void *);

protected:
virtual void Run() {};
static void *EntryPoint(void *);
void *Arg() const {return arg;}

private:
pthread_t thread;
void *arg;
};

//*************************** CLASE THREAD ************************************

//************************** CLASE DERIVADA ******************************
class ClaseEredadaThread : public Thread{
private:
void Run();
};
//************************** CLASE DERIVADA ******************************

//************************** METODOS *************************************
int Thread::Start(void *a)
{
arg = a;

int result = pthread_create(&thread, NULL, Thread::EntryPoint, reinterpret_cast<void *>(this));

if (result!=0)
{
return(pthread_detach(thread));
}
return(result);
}

void *Thread::EntryPoint(void *pthis)
{
Thread *pt = reinterpret_cast<Thread *>(pthis);
pt->Run();
return 0;
}
void ClaseEredadaThread::Run()
{

int tamanho_buf_out=0,i,k,tamanho_buf_out_cab=0,enviad o;//tamanho de datos del buffer de salida
int recv_size;//guardamos el tamaño de datos recibidos del cliente
int tamanho_fichero=0,index=0,continua=1;
int connection_close;
struct stat estado;
char c;
char tipo_html[]=".html";
/*char tipo_txt[]=".txt";
char tipo_imagen1[]=".jpg";
char tipo_imagen2[]=".bmp";
char tipo_imagen3[]=".jpeg";
char tipo_imagen4[]=".gif";
char tipo_imagen5[]=".png";
char tipo_imagen6[]=".ico";*/
char indice[]="index.html";
//char tipo_get[]="GET";
//char http11[]="HTTP/1.1";
//char http10[]="HTTP/1.0";
char con_close[]="Connection: close";
char host_name[]="Host:";
//char modificacion[]="If-Modified-Since:";
char solicitud[30];
ifstream f_entrada;
char BUFFER_IN[TAMANHO_BUFFER];//buffer donde almacenamos los datos de la petición
char BUFFER_OUT[TAMANHO_BUFFER];//buffer donde almacenamos la cabecera de la respuesta
char *p_buffer;//buffer de memoria dinamica donde almacenamos los datos de la respuesta
char *p_aux;
char *p_aux2;
int clnt_sock= *(reinterpret_cast<int *>(Arg()));

while (continua==1)
{
continua=0;
enviado=0;
cout<<"** Hilo en socket "<<clnt_sock<<". "<<endl;

//Hacemos un recv para recibir los datos del cliente




memset(&BUFFER_IN, '\0', TAMANHO_BUFFER);
recv_size = recv(clnt_sock,BUFFER_IN,TAMANHO_BUFFER,0);




if(recv_size==-1)
{
cout<<"Error al hacer el recv"<<endl;
exit(0);
}


//Lee el nombre del archivo pedido, buscando el espacio despues del nombre
for(i=4; i< recv_size;i++)
{
if(BUFFER_IN[i]==' ')
{
k=i;
break;
}
}

memcpy(solicitud,&BUFFER_IN[5],k-5);

solicitud[k-5]='\0';//si no pidio nada, guardamos index.html en "solicitud"

if(k==5)
{
memcpy(solicitud,indice,strlen(indice));
solicitud[strlen(indice)]='\0';
}

connection_close=0;
for(i=0;i<recv_size;i++)
{//Si solicitan close
if (memcmp(&BUFFER_IN[i],con_close,strlen(con_close))==0)
{
cout<<"Piden que cerremos la conexion"<<endl;
connection_close=1;
}
}
int error_host=1;
for(i=0;i<recv_size;i++)
{//Si falta el campo Host
if(memcmp(&BUFFER_IN[i],host_name,strlen(host_name))==0)
{
error_host=0;
}
}

tamanho_buf_out=0;
memset(&BUFFER_OUT, '\0', TAMANHO_BUFFER);
/*
if(memcmp(&BUFFER_IN[k+1],http10,strlen(http10))==0)
{//si es http 1.0 cerramos conexion
char cad[]="HTTP/1.0 200 OK\n";
memcpy (&BUFFER_OUT[0],cad,strlen(cad));
tamanho_buf_out=strlen(cad);
char cad2[]="Connection: close\n";
memcpy (&BUFFER_OUT[tamanho_buf_out],cad2,strlen(cad2));
tamanho_buf_out=tamanho_buf_out+strlen(cad2);
}
else{*///si es http1.1 dejamos la conexión abierta (conexiones persistentes hasta recibir un connection CLOSE)
char cad[]="HTTP/1.1 200 OK\n";
memcpy (&BUFFER_OUT[0],cad,strlen(cad)+1);
tamanho_buf_out=strlen(cad);
if(connection_close==1)
{//cerramos conexion
char cad2[]="Connection: close\n";
memcpy (&BUFFER_OUT[tamanho_buf_out],cad2,strlen(cad2));
tamanho_buf_out=tamanho_buf_out+strlen(cad2);
}
else{//dejamos la conexion abierta
//cout<<"Entro conexion abierta"<<endl;

continua=1;
char cad2[]="Keep-Alive: 115\n";
memcpy (&BUFFER_OUT[tamanho_buf_out],cad2,strlen(cad2));
tamanho_buf_out=tamanho_buf_out+strlen(cad2);
/*char cad3[]="Connection: keep-alive\n";
memcpy (&BUFFER_OUT[tamanho_buf_out],cad3,strlen(cad3));
tamanho_buf_out=tamanho_buf_out+strlen(cad3);*/
}
// }



if(memcmp(solicitud + strlen(solicitud)-5,tipo_html,strlen(tipo_html))==0)//si elimino esta parte no me da error
{

cout<<"Se solicita web: "<<solicitud<<"."<<endl;
f_entrada.open(solicitud);
while (!f_entrada.eof())
{
f_entrada.get(c);
tamanho_fichero++;
}
f_entrada.close();
tamanho_fichero--;
char cad4[]="Content-Type: text/html\nContent-Length: ";
memcpy (&BUFFER_OUT[tamanho_buf_out],cad4,strlen(cad4));
tamanho_buf_out=tamanho_buf_out+strlen(cad4);
char numero[255];
tamanho_fichero=sprintf (numero, "%d\n\n", tamanho_fichero);
memcpy (&BUFFER_OUT[tamanho_buf_out],numero,strlen(numero));
tamanho_buf_out=tamanho_buf_out+strlen(numero);
f_entrada.open(solicitud);

i=tamanho_buf_out;
tamanho_buf_out_cab=tamanho_buf_out;
while (!f_entrada.eof())
{//lee mientras no acabe el fichero (End Of File)
f_entrada.get(c);
i++;
}
f_entrada.close();
tamanho_buf_out=i-1;//ya tenemos en BUFFER_OUT lo que hay que enviar

//CREAMOS MEMORIA DINAMICA
p_buffer = new char[tamanho_buf_out];
p_aux=p_buffer;
p_aux2=p_buffer;

for(int x=0; x<tamanho_buf_out_cab;x++)
{
memcpy (p_aux,&BUFFER_OUT[x],1);
p_aux++;
}
f_entrada.open(solicitud);
while (!f_entrada.eof()){//lee mientras no acabe el fichero (End Of File)
f_entrada.get(c);//lee un caracter del fichero y lo guarda en la variable c
memcpy (p_aux,&c,1);
p_aux++;
}
f_entrada.close();

//cout<<"Buffer dinamico de tamanho: "<<tamanho_buf_out<<", para "<<solicitud<<"."<<endl;
for(int x=0; x<tamanho_buf_out;x++)
{
p_aux2++;
}

//cout<<"Envia lo de memoria dinamica"<<endl;
if(send(clnt_sock,p_buffer,tamanho_buf_out,0)!=tam anho_buf_out)
{
cout<<"Error al hacer send de memoria dinamica"<<endl;
exit(1);
}
//cout<<"Enviado lo de memoria dinamica"<<endl;

delete [] p_buffer;//liberamos la memoria dinamica
enviado=1;
}

//cout<<"solicitud "<<solicitud<<"."<<endl;


//Enviamos lo del BUFFER_OUT al cliente
/*if (enviado==0){
if(send(clnt_sock,BUFFER_OUT,tamanho_buf_out,0)!=t amanho_buf_out)
{
cout<<"Error al hacer send del BUFFER_OUT"<<endl;
exit(1);
}
}*/
//continua=0; o si lo obligara de esta manera a salir del while y cerrar cada hilo pero es que debería quedarse a la escucha para seguir con las peticiones que se le mande
}//fin del while
close(clnt_sock);
cout<<"Cerramos el hilo "<<clnt_sock<<"."<<endl;
return;
}
//************************** METODOS *************************************


//*************************** MAID ************************************
int main(int argc, char *argv[])
{
int n;//contador de pruebas******
int puerto;
int serv_sock;//este es el identificador del socket del servidorAddress, de nuestro programa
int clnt_sock;//este es el identificador del socket del clienteAddress que se conecta conmigo
struct sockaddr_in servidorAddress;//para la información de la dirección del servidorAddress
struct sockaddr_in clienteAddress;//para la información de la dirección del clienteAddress
socklen_t clnt_len;
ClaseEredadaThread *eth;
eth=new ClaseEredadaThread();

if (argc != 2){
cout<<"Introduzca el numero de puerto"<<endl;
exit (0);//sale del programa
}
puerto= atoi(argv[1]);//recogemos el dato de entrada y lo convertimos en una variable de tipo int



if ((serv_sock=socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
cout<<"Error en el socket()"<<endl;
exit(-1);
}

servidorAddress.sin_family = AF_INET;
servidorAddress.sin_addr.s_addr = htonl(INADDR_ANY);//coloca nuestra dirección IP automáticamente
servidorAddress.sin_port = htons(puerto);

if(bind(serv_sock,(struct sockaddr*)&servidorAddress,
sizeof(struct sockaddr))==-1) {
cout<<"Error en bind() "<<endl;
exit(-1);
}

if(listen(serv_sock,BACKLOG) == -1) {
cout<<"Error en listen()"<<endl;
exit(-1);
}

cout<<"El socket está en estado LISTEN en el puerto "<<puerto<<"..."<<endl;


clnt_len = sizeof(struct sockaddr_in);

while(1)
{//bucle infinito que lanza un hilo en cada accept recibido
clnt_sock = accept(serv_sock,(struct sockaddr *)&clienteAddress,&clnt_len);
if(clnt_sock<0){
cout<<"Error al hacer accept con el clienteAddress"<<endl;
exit(0);
}

//cout<<"dirección: "<<&clnt_sock<<"."<<endl;
eth->Start(&clnt_sock);//lanzamos el hilo para este clnt_sock


}
return 0;
}
//*************************** MAID ************************************

Etiquetas: bucle, fichero, hilos, int, programa, socket, variables
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:22.