Servidor Web en Windows [C]

Iniciado por madox, 6 Octubre 2013, 21:33 PM

0 Miembros y 2 Visitantes están viendo este tema.

madox

Actualizar página de Webserver

Hola comunidad, quiero hacer un server el cual se debe actualizar cuando el cliente modifica algo de la página. Como verán lo hago leyendo el método GET.
El problema es que en la segunda pasada el programa se cuelga. No sé como manejar el socket abierto(la condición para mantener la conexión) . O tal vez queda el buffer de recepción con basura.
¿ Alguna idea?. Gracias por leerme.

La parte en la que armo la página es ésta;


while(1){  
       
             
// Aceptamos conexiones entrantes
  printf("Esperando conexiones entrantes... \n");
  stsize=sizeof(struct sockaddr);  
 
 
  comm_socket=accept(conn_socket,(struct sockaddr *)&client,&stsize);

   
if (comm_socket){
   printf("Conexion entrante desde: %s\n", inet_ntoa(client.sin_addr));
   memset (SendBuff, 0, sizeof SendBuff);
   if(a=1){ //mando la pagina original
   strcpy(SendBuff,pagina);    
   send (comm_socket, SendBuff, sizeof(SendBuff), 0);
   a=0;
   }
   else{
        strcpy(SendBuff,pagina2);    //esta página sera la modificable
        send (comm_socket, SendBuff, sizeof(SendBuff), 0);
        }        
     
     
       if(recv (comm_socket, RecvBuff, sizeof(RecvBuff), 0)){
         
               recv (comm_socket, RecvBuff, sizeof(RecvBuff), 0);
   
                               puts("entre a armar");
         
                               armar_pagina();

  }
                    strcpy(SendBuff,pagina2);
                    puts(pagina2);
                    send (comm_socket, SendBuff, sizeof(SendBuff), 0);  
                    puts("aquiiiiii");
                    closesocket(comm_socket);

}

eferion

Cuando tu configuras el socket del servidor, lo tienes que configurar de tal forma que cuando te llega una petición, recibes un identificador de la conexión.

ese identificador actúa sobre el socket abierto... pero es independiente del socket. Esto quiere decir que tú el identificador debes cerrarlo después de enviarle la respuesta al cliente y quedar a la espera de que el socket te pase otro identificador.

Cuando tu cierras un identificador el socket sigue abierto. Lo que te debe estar pasando es que tú cierras el socket y, claro, cuando el cliente intenta una segunda conexión no puede contactar con el servidor porque éste ha cerrado la conexión... o eso o tu programa tiene un fallo y no se queda a la espera de nuevas conexiones.

madox

el identificador lo obtengo asi;
Primero creo el socket...
   conn_socket=socket(AF_INET,SOCK_STREAM, 0);
al conectarse un cliente abro un nuevo id;
comm_socket=accept(conn_socket,(struct sockaddr *)&client,&stsize);
es asi no?
por eso pongo la condición que me actualiza los valores de la página mientras el socket permanezca activo;
while(comm_socket!=-1)
lo que yo hago, una vez que mando la pagina es :
closesocket(comm_socket);
y vuelvo a esperar conexiones.

eferion

Revisando más detenidamente tu código, efectivamente, la línea con la que tienes dudas está mal.

Lo que tienes que comprobar es que la conexión sigue abierta... pero tienes que pensar que el hecho de que la conexión se cierre no va a implicar que a ti, por arte de magia, se te modifique el identificador de la conexión.

Una forma que puedes utilizar para detectar esto es comprobar si recv te devuelve 0.

Al haber configurado la conexión como bloqueante, al intentar una lectura el programa se quedará congelado en dicha función hasta que se reciba algo por parte del cliente o bien se cierre la conexión.

madox

Que tal eferion gracias por tu interes en mi problema,
sabes que sigo teniendo lio con recv ya que parece que el cliente nunca deja de mandar datos, porque aunque yo no toque ningún botón  el programa sigue corriendo como si recv no fuera bloqueante. Ahora estoy analizando al cliente de esta manera para luego armar la pagina:

if(recv (comm_socket, RecvBuff, sizeof(RecvBuff), 0)){

      armo la página con los cambios
}


apenas cargo la pagina entra al recv.
Habrá otra forma de saber cuando modifica algo el cliente?

eferion

Veo que no tienes muy claro el protocolo http.

En el protocolo Http el servidor únicamente se limita a proporcionar al cliente la información que éste solicita y después corta la conexión.

Si un cliente, en un momento dado, requiere un refresco de la información ha de solicitárselo al servidor creando una nueva conexión.

El servidor en ningún momento guarda un listado de los clientes que estén viendo una página alojada en el mismo.

Dicho esto, las comunicaciones básicas que se han de dar son las siguientes:

1. Cliente envía la petición
2. Servidor responde a la petición
3. Servidor cierra la conexión

Como ves, en ningún caso el servidor se queda esperando a ver si el cliente tiene algo más que decir. Y dado que el protocolo de red empleado es TCP, la propia lógica del protocolo permite asegurar que la información ha llegado correctamente.

Si el cliente necesita algo más tendrá que volver a establecer una nueva conexión con el servidor.