Stratos

Autor Tema: Duda Winsock  (Leído 2419 veces)

Lord Trancos 2

  • Stratos
  • Mensajes: 1226
    • Ver Perfil
Duda Winsock
« en: 01 de Marzo de 2006, 11:04:32 pm »
 Estoy haciendo un programita con sockets asincronos, y me preguntaba si hay algun modo de comprobar en cualquier momento si el socket esta conectado.

¿seria correcto hacerlo mirando el valor de SO_CONNECT_TIME?
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
http://gatetoavalon.blogspot.com/' target='_blank'>Gate to Avalon (mi Blog)

Lord Trancos 2

  • Stratos
  • Mensajes: 1226
    • Ver Perfil
Duda Winsock
« Respuesta #1 en: 14 de Marzo de 2006, 12:23:07 am »
 Nadie puede echarme un cable?  :rolleyes:  
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
http://gatetoavalon.blogspot.com/' target='_blank'>Gate to Avalon (mi Blog)

Warchief

  • Stratos
  • Mensajes: 918
    • Ver Perfil
    • http://www.telefonica.net/web2/warchief/
Duda Winsock
« Respuesta #2 en: 14 de Marzo de 2006, 12:35:09 am »
 ¿Te refieres a saber si la comunicación se ha caído?

No he trabajado con Winsock, pero sí con los sockets de Unix. Allí, una manera de mirar eso era con un recv (recibir mensaje). Con el flag MSG_PEEK se intenta coger datos, pero no se eliminan del propio buffer. Si la función devuelve el dato o un indicador que se habría quedado bloqueado de no ser bloqueante, es que la conexión está OK. Si devuelve un error de conexión no hay más historia.

Supongo que Winsock tiene algo parecido para hacer peek.

Ejemplo parecido (no hace peek, pero trata los datos instantáneamente):
Código: [Seleccionar]
 // Mientras que no haya que cerrar el programa ni se haya caído el cliente
  while(!finalizarHijos && !caido) {
    
    // Intentar leer (no bloqueante)
    bytesRecibidos = recv(datos->m_socket, mensaje, MAX_MENSAJE, MSG_DONTWAIT);
    // Error leyendo
    if( bytesRecibidos  < 0 ) {
      if(errno != EAGAIN)
util_error_cad("[serverH] Fallo al recibir mensaje a través de socket.", strerror(errno) );  
    }
    // Recibido un nuevo mensaje. Procesar
    else if(bytesRecibidos > 0) {
      
      server_procesarMensajeRotella(mensaje, datos);
      
      // Resetear mensaje del cliente
      bzero(mensaje, MAX_MENSAJE);  
    }
    // Si se lee EOF es porque el otro lado ha terminado/caído (cerrado el socket)
    else {
      caido = 1;
      util_debugMSG_int("[serverH] Se ha desconectado un cliente. Cerrando hilo...", datosHilo->m_numHilo);
    }
    
    // Esperar un tiempo para no saturar al procesador  
    usleep(ESPERA_HILO_CONEXION_USEC);  
    
    fflush(stdout);
  } // Mientras no haya que salir

En este bucle, si al leer hay error se indica el error sucedido. EAGAIN indica que se habría bloqueado, por lo que la conexión parece estar activa (no se considera error). En ese caso se continúa normalmente.

En cuanto se reciben datos procesa el mensaje (puede no ser correcto ya que en los sockets TCP no está asegurada la entrega completa del mensaje original, pero para mi caso era suficiente).

Si la llamada devuelve 0 no hay error y no habrá datos. Se ha leído EOF, y por tanto la conexión está cerrada.

Espero que sirva como orientación.
In the end, my opinion is that the largest deficiency for game AI is that it fails the Turing Test.
Horribly.

Link[in]