Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 28-02-2008
rolandoj rolandoj is offline
Miembro
 
Registrado: abr 2007
Posts: 395
Poder: 18
rolandoj Va por buen camino
Question Indy: Connection clode gracefully. Completas causas y solución ?

Hola,

Perdón por abrir esto como un hilo nuevo cuando no solo hay hilos antiguos sino que hace pocas horas se acaba de cerrar uno al respecto (vease http://www.clubdelphi.com/foros/showthread.php?t=53705); pero, en esos hilos el objetivo fué resolver el problema de alguién y creo en cambio que el problema amerita una discusión general

Yo también me he encontrado muy recientemente con el error "Connection closed gracefully" (tengo Delphi 2007 Update 3 con Indy 10)

Una investigación en Internet indica que el error es frecuente, tan frecuente que incluso un miembro del equipo Indy escribió una larga explicación al respecto, la cual puede consultarse aquí:

http://www.swissdelphicenter.ch/en/showarticle.php?id=1

Cuando se pregunta por este problema, quienes contestan usualmente mandan a leer esa nota; pero, hay varios inconvenientes con ella que creo ameritan un hilo especial:

La explicación es teóricamente extensa y se puede decir que buena; pero, desde el punto de vista práctico, no explica los puntos más importantes que necesitamos tener en cuenta los programadores.

Antes todo, aclaro que el principal consejo que se dá es para que el mensaje no moleste cuando se está depurando; pero, en mi caso, y supongo que a otros también les ha pasado, el problema no lo tenía al depurar, sino en la versión "productiva".

Un punto clave que no explica es como detectar la verdadera causa del error. Veamos :

El caso en que se dispare en un servidor, puede ser un verdadero error, o una exception. Yo no le experimentado; pero, la nota no dice como saber cuando es un error y cuando una excepción.

El caso de que el mensaje se dispare en un cliente (en mi caso se dispara al llamar al método Get de TIdHTTP), dice que corresponde a un verdadero error y debe ser manejado atrapandolo; sin embargo, no explica exactamente que causa el error.

En ambos casos, la explicación general es que se trata de que al menos uno de los dos equipo cierra la conexión, y que en algunos protocolos es algo normal, parte de su propia convención.

En mi caso, esa explicación general no la encuentro aplicable porque de casi 100 llamadas distintas al servidor, ya he probado la gran mayoría y solo en una se presenta, y con mucha frecuencia. Si correspondiera a esa explicación debería ocurrir en bastantes más llamadas.

Concluyo que en mi caso es un verdadero error; pero, por qué ?, en cuales circunstancias ?. Por qué el comando a veces funciona y a veces no (en especial siendo uno en que la operación es corta) ?. La nota no dá ninguna pista clara para responder esto.

Ahora bien, tampoco explica como debe exactamente manejarse el error.

Yo he implementado una solución usando un contador de intentos; así, si se produce el error, incremento el contador y repito la llamada. Logicamente si excede el máximo de intentos (lo ajusté a 4), lo tomó como un problema definitivo y reporto al usuario.

Este enfoque me ha funcionado muy bien; pero, por un lado, en la llamada del problema, el tiempo de respuesta no es bueno (claramente, con frecuencia se necesitan varios intentos), por otro lado, ese tipo de solución a "prueba y error" no me parece confiable, ni presentable desde
el punto de vista técnico.

De hecho, en el fondo es similar a la solución dada en otro hilo usando en "delay" entre llamadas.

En otros hilos y notas al respecto, he visto mencionar como causa la versión de Indy; pero no parece ser algo directamente relacioando con la versión.

Ojalá puedan comentar al respecto, a ver si puede aclararse el tema.

Última edición por rolandoj fecha: 28-02-2008 a las 20:58:40.
Responder Con Cita
  #2  
Antiguo 29-02-2008
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cita:
Empezado por rolandoj Ver Mensaje
Un punto clave que no explica es como detectar la verdadera causa del error. Veamos :
Si explica cual es la causa del error:

Cita:
Empezado por Chad Z. Hower
EIdConnClosedGracefully is an exception signaling that the connection has been closed by the other side intentionally. This is not the same as a broken connection which would cause a connection reset error. If the other side has closed the connection and the socket is read or written to, EIdConnClosedGracefully will be raised by Indy. This is similar to attempting to read or write to a file that has been closed without your knowledge.
Cita:
Empezado por rolandoj Ver Mensaje
El caso de que el mensaje se dispare en un cliente (en mi caso se dispara al llamar al método Get de TIdHTTP), dice que corresponde a un verdadero error y debe ser manejado atrapandolo; sin embargo, no explica exactamente que causa el error.
Un servidor HTTP regularmente cerrará la conexión después de cada get/post, a menos que se haya enviado una cabecera indicándole que mantenga viva la conexión... y aún así podría no hacerlo a su sola discreción. Creo que lo mejor es que hables con el administrador de dicho servidor o que repases la manera en que estas empleando el protocolo.


Cita:
Empezado por rolandoj Ver Mensaje
En mi caso, esa explicación general no la encuentro aplicable porque de casi 100 llamadas distintas al servidor, ya he probado la gran mayoría y solo en una se presenta, y con mucha frecuencia. Si correspondiera a esa explicación debería ocurrir en bastantes más llamadas.
Aún cuándo la llamada sea la misma, puede ser que algo ocurra en el servidor y no estés procesando correctamente la respuesta. Por ejemplo, un servidor podría devolver un error 500 debido a una condición interna de error e inmediatamente después cerrar la conexión.
Un cliente HTTP robusto deberá procesar correctamente todas las respuestas probables de un servidor, y no esperar tener únicamente status 200.

Cita:
Empezado por rolandoj Ver Mensaje
En otros hilos y notas al respecto, he visto mencionar como causa la versión de Indy; pero no parece ser algo directamente relacioando con la versión.
¿con cuantas versiones de INDY has trabajado?

Yo relaciono mensajes de error "connection closed gracefully" con la versión debido a que en versiones de INDY 9 previas a la 9.0.18 (ya no logro recordar en cuales exactamente), esta excepción particular no era bien manejada internamente dentro de INDY, por lo que salía al exterior cuándo no existía realmente o era posible manejarla.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #3  
Antiguo 29-02-2008
rolandoj rolandoj is offline
Miembro
 
Registrado: abr 2007
Posts: 395
Poder: 18
rolandoj Va por buen camino
Smile Gracias. Comentarios

Hola,

Muchas gracias por las respuestas. Tengo varios comentarios:

1. Cuando yo hablo de que no explica como detectar la verdadera causa del error me refiero a que, si alguno de los lados cierra la conexión, debe ser por un motivo. Uno, el caso normal que no debe considerarse como error, lo explican como causado por la misma convención del protocolo; pero, el otro, o sea cuando es un verdadero error, no explican que puede causarlo ni como detectarlo en nuestro código, ya que decir que uno de los dos lados cierra la conexión es indicar la manifestación final; pero no la causa original.

Para ponerlo más claro en términos de códigos, lo ilustro con mi metodología:

Cuando tengo una serie de llamadas anidadas, en cada una de las cuales se pueden producir errores, yo voy atrapandolos en cada una de ellas, y lo hago con un mensaje que muestra un código de error y una descripción del mismo correspondiente al bloque; al final incluyo, el error que viene de la rutina inmediatamente anidada. De esta forma, el mensaje final de error es largo (incluso 4 o 5 anidados); pero permite determinar la ruta exacta del error.

Según la explicación dada para este problema de conexión, aparentemente se
dispara el mensaje más interno y no se incluye ninguna información de porque o donde se generó. Igualmente, no indica que deberíamos revisar cuando se trate de verdaderos errores.

Por lo anterior, aún cuando he leído con cuidado los mismos parrafos que publicas de esa nota (y toda la nota), no estoy de acuerdo en que sea una explicación completa para la situación.

2. Mi código para atrapar errores es metodológicamente muy robusto, como habrás notado de la observación anterior. En mi caso, aparte de desplegar mensajes de error largos, no solo atrapo los códigos de error propios de la convención; sino que también una serie de códigos de error personalizados que envío para detectar acciones que requieren manejo especial. De hecho, atrapo todo lo posible, no solo lo probable.

En el caso de nuestro mensaje, la excepción se dispara; pero el servidor
está enviando el código 200. Debido a eso, inicialmente me sorprendió porque no estaba usando el "Exception" para analizar el mensaje, sino que cuando atrapaba la excepción, solo validaba usando ResponseText y ResponseCode. Obviamente, ya cambié ese código porque ya no confío exclusivamente en los códigos de error del servidor.

3. Cuando dices:

Cita:
Empezado por jachguate Ver Mensaje
Aún cuándo la llamada sea la misma, puede ser que algo ocurra en el servidor y no estés procesando correctamente la respuesta. Por ejemplo, un servidor podría devolver un error 500 debido a una condición interna de error e inmediatamente después cerrar la conexión.
Entiendo que me estás dando la razón de que hay algún problema en el servidor; pero es un problema específico de la llamada, y la gran pregunta es por qué a veces contesta perfecto y en otras no dice nada ?. Considerando que encima el requerimiento es sin parámetros, resulta aún más extraño, ya que todas las veces debería hacer exactamente el mismo recorrido. Una de las dos grandes preguntas por las que abrí este hilo es : Como hacer para detectar la causa de estos casos ?

4. He usado, y uso, las versiones 8, 9 y 10 de Indy. En este momento, el
problema se presenta en la versión 10 que viene con el Update 3 de Delphi.
De todas formas, cuando digo que no parece algo relacionado con la versión es porque me pasa con la última (o casi última, no me he fijado si sacaron algo más) y he leído referencias de personas que lo han sufrido en diversas versiones.

5. Veo que no comentastes nada acerca de como manejarlo ?. Que metodología usas ?

Muchos saludos
Responder Con Cita
  #4  
Antiguo 02-09-2008
davi_dk davi_dk is offline
Registrado
 
Registrado: sep 2008
Posts: 2
Poder: 0
davi_dk Va por buen camino
Yo tambíen me tropecé con este error recientemente. La solución lo leí en otro foro.
Utilizo C++Builder 6 con componentes Indy 9.17x pero creo que funciona para versiones superiores también

Ejemplo de código:
Código PHP:
try
    {
      
ftpClient->List(NULL"*.*"true );
    }
    catch( const 
EIdConnClosedGracefully &)
    {
      
/**
      * El mensaje de 'EIdConnClosedGracefully' lo tienes meter dentro de
        Tools->Debugger Options->Language Exceptions para que lo ignore 
        C++Builder. Sino, no funciona      */
    

Davi
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Que Significa el Error "connection Closed Gracefully" en los Indys ???? AGAG4 Varios 6 26-03-2009 23:01:59
Como reemplazar Indy 10 por Indy 9 en Delphi 2007 ? rolandoj Internet 0 13-02-2008 18:44:31
Debate: Causas del fracaso de Kylix rretamar Debates 22 13-03-2007 04:48:15
pasar palabras completas de un memo a otro Cosgaya Conexión con bases de datos 1 05-06-2005 15:41:07
Imprimir tablas completas en Rave Oreades Impresión 1 07-06-2004 07:43:40


La franja horaria es GMT +2. Ahora son las 18:53:21.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi