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 05-05-2010
vejerf vejerf is offline
Miembro
 
Registrado: ene 2007
Posts: 206
Poder: 18
vejerf Va por buen camino
Aplicación Cliente/Servidor no bloqueante

Hola a tod@s,

Estoy desarrollando una aplicación cliente/servidor. Cuando el cliente se conecta al servidor le envía toda la información que este posee y cada vez que la renueva se la reenvía.

El problema me ha surgido cuando estando el programa corriendo el ordenador con la aplicación servidora se me ha reiniciado y esto no le ha gustado para nada a la aplicación cliente que se me ha quedado completamente colgada.

Estoy usando los componentes indy TIdTCPServer y el TIdCmdTCPClient.

No sé si lo que me ha pasado tiene que ver con que son componentes que establecen sockets bloqueantes y por ahí he leído que lo suyo es ponerlo a trabajar con hilos pero no tengo ni idea de como hacerlo.

Si no es por esto supongo que el corte súbito sin realizar la desconexión es lo que me ha causado este problema, pero como podría controlar esto?

Muchas gracias a todos!!!
__________________
"Patientia et constantia taelecum"
Responder Con Cita
  #2  
Antiguo 05-05-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Hola vejerf,

Si se te ha quedado "congelado" el cliente, es probable que sea porque esté haciendo un read en el buffer. Como el servidor no llega a responder, el cliente se queda esperando a que le llegue información por el buffer.

Lo del hilo es buena idea, ya que la lectura y escritura del cliente quedaría en un segundo plano y no te congelaría el hilo principal, que es el que atiende las peticiones del usuario.

No obstante, hacer un hilo tiene sus dificultades y tienes que dominar muy bien la técnica para que todo te funcione correctamente.

Una cosa que puedes intentar y que será más fácil es a indicar un TimeOut de lectura del buffer:
Código Delphi [-]
IdTCPClient1.ReadTimeout := 1000;

Para mayor seguridad, lo podrías implementar también el servidor, para cuando se te de el caso contrario.

Ya me cuentas cómo te va con esto. Si no te soluciona tu problema, comentamos cómo lo podrías hacer un un hilo secundario.

Espero que te ayude.

Un saludo.
Responder Con Cita
  #3  
Antiguo 06-05-2010
vejerf vejerf is offline
Miembro
 
Registrado: ene 2007
Posts: 206
Poder: 18
vejerf Va por buen camino
Hola Manuc,
Primero darte las gracias por tu respuesta y segundo comentarte un par de dudas que sigo tenido a ver si saber resorvérmelas.

Supongo que la propiedad ReadTimeout es el máximo tiempo que espera el componente para realizar una lectura. Pero tengo la duda sobre lo que ocurre si pasa este tiempo, no sé si se aborta la lectura o se cierra la conexión.

Suponiendo que se cierre la conexión entonces debería hacer que tanto el cliente como el servidor se envíen algún mensaje cada cierto tiempo diciendo "estoy vivo".

Voy a implementar esto y si no me funciona pues supongo que tendré que recurrir a los hilos, que aunque más complicado como dices creo que debe ser la solución más apropiada para estos casos.

Por otra parte tengo otra duda que no sé si sabrás respondérmela y es que yo para comunicarme usaba:
Código Delphi [-]
Cliente.IOHandler.WriteLn(Trama);

Sin embargo he visto que también posee la propiedad Socket con lo que se podría hacer supongo:
Código Delphi [-]
Cliente.Socket.WriteLn(Trama)

¿Qué diferencia hay entre una forma y otra si hay alguna?

Muchas gracias de nuevo!!!
__________________
"Patientia et constantia taelecum"
Responder Con Cita
  #4  
Antiguo 08-05-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Hola vejerf,

Ciertamente "ReadTimeout" te desconectará del servidor tras superar el periodo de inactividad.

En una aplicación cliente que tiene que estar constantemente "escuchando" al servidor, es un complicado decidir qué tiempo es el más razonable para establecer el ReadTimeout.

Por un lado, si estableces un timeout muy pequeño, tendrás que hacer lo que comentas, generar actividad simplemente para que los hilos no se desconecten, con el riesgo de crear tráfico de red innecesario.

Por otro lado, si lo estableces muy alto, cuando tu servidor se cuelgue, el cliente tardará tiempo en darse cuenta y se quedará congelado.

Pero una pregunta: ¿tu software cliente está constantemente esperando respuesta por el servidor? o ¿es el servidor el que espera comandos y emite respuetas al cliente?

Respecto a la diferencia entre IOHandler y Socket, no sabría decirte qué diferencias existe entre ambos.

Un saludo.
Responder Con Cita
  #5  
Antiguo 10-05-2010
vejerf vejerf is offline
Miembro
 
Registrado: ene 2007
Posts: 206
Poder: 18
vejerf Va por buen camino
Hola de nuevo Manuc,

Te cuento un poco de que va la aplicación. Resulta que estamos desarrollando una aplicación que controla la actualización de unos elementos en una sede. Pues resulta que hay varias sedes y una sede central. La idea es realizar una aplicación para las distintas sedes y una para la central. La central recibirá toda la información de las otras sedes cuando estas se conecten y cuando actualicen algún elemento.

Mi idea ha sido hacer una aplicación basada en TCP donde las distintas sedes tengan una aplicación cliente que se conectarán a la sede central donde residirá la aplicación servidora, pero en principio esta no tiene por qué enviar nada sino sólo los clientes enviarán información cuando se actualice algún elemento.

Esta es la filosofía básica de funcionamiento. Después cada elemento de cada sede se pueden actualizar a intervalos de 15min o incluso más por lo que es difícil estimar un tiempo.

Saludos!
__________________
"Patientia et constantia taelecum"
Responder Con Cita
  #6  
Antiguo 10-05-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Hola vejerf,

Atendiendo a lo que me comentas, mi recomendación seria que cada cliente conecte al servidor, solo, cuando tenga algo para enviar al mismo.

El protocolo sería algo así:
- El cliente detecta cambios para enviar al servidor.
- Conecta al servidor.
- Establece el "ReadTimeout".
- Envía la información al servidor.
- Espera el "OK" del servidor
- Desconecta del servidor.

Por otro lado, el servidor al recibir la conexión también debe establecer la propiedad "ReadTimeout" de la conexión, para evitar que se queden hilos colgados en el servidor (cuando un cliente pierda la conexión de forma inesperada).

Sin querer me he encontrado un ejemplo de idTCPClient que casualmente utiliza un hilo secundario en la aplicación cliente.

Te lo dejo aquí por si te interesa verlo.

Realmente todo esto depende mucho de la estructuración de tu proyecto, de la cantidad de "paquetes" a enviar al servidor, de lo que el servidor tenga que hacer con esos paquetes, etc.

Espero que te ayude.

Un saludo.
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
aplicación cliente servidor? Giniromero Conexión con bases de datos 12 25-10-2006 04:39:18
Aplicacion Cliente-Servidor D-MO Varios 2 01-09-2005 00:37:42
Aplicación Cliente Servidor NickName Internet 3 23-07-2004 15:07:22
Aplicacion cliente servidor aguilot_21 Internet 3 26-12-2003 02:07:55
Aplicacion Cliente - Servidor GIVO Conexión con bases de datos 0 30-07-2003 23:33:14


La franja horaria es GMT +2. Ahora son las 22:06:39.


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