Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   DUDA Recursos de Red (https://www.clubdelphi.com/foros/showthread.php?t=40113)

ArdiIIa 07-02-2007 17:53:57

DUDA Recursos de Red
 
Pss, Pss...
Tengo una aplicación en una empresa desde hace bastante tiempo y va muy bien... PERO.... Resulta que cuando aparece por la empresa el técnico de turno, lo fastidia todo y no es capaz de recomponerlo.
Esto ocurre cuando adquieren un nuevo ordenador o formatean uno viejo o simplemente cambian el nombre de una máquina en red.
El programa en su módulo de configuración, dispone de un apartado para configurar la BD o más concretamente su path, además de un Test de conexión para verificar esa ruta. A pesar de las explicaciones que doy de instalar Firebird y de configurar ese path, resulta que el técnico, al parecer no quiere pecar de "pringao", desentendiéndose de todo aquello que no sea formatear...
Lo cierto y verdad es que como quiera que son varios los ordenadores que acceden por red a la BD, me gustaría montar un sistema capaz de auto configurarse y que fuera capaz de localizar por la red por las diferentes máquinas, justamente en la cual se encuentra la BD.
Realmente no se como abordarlo, supongo que
  • En primer lugar tendría que saber todas las máquinas que están en la red...
  • Y en segundo lugar, por ejemplo, hacer alguna prueba con el puerto 3050 para ver si pita...

En el primer punto, ya me pierdo...

En fin, la idea es detectar el path (incluida la IP o nombre la la máquina) donde se encuentra la Base de Datos.

seoane 07-02-2007 18:09:22

El tema parece interesante. :)

Una primera aproximación sería obtener la ip de la maquina en la que estamos, su mascara de subred, y a partir de ahí ir comprobando, en todas las ips posibles de la subred, cual tiene el puerto 3050 abierto. Esto es lento, los intentos de conexión fallidos tardan mucho en detectarse.

Otra posible solución es utilizar UDP. En el servidor tenemos un pequeño programa que este escuchando por un puerto UDP. Cuando una aplicación dentro de la red local quiere averiguar la ip del servidor solo tiene que enviar un mensaje UDP a la dirección de broadcast de forma que todos los equipos lo recibirán a la vez. Entonces el programa que esta escuchando responderá con otro mensaje, esta vez directamente a la ip del equipo que preguntaba. Incluso puede enviarle la ruta completa, o cualquier otra información de configuración que consideres necesaria.

¿que te parece?

ArdiIIa 07-02-2007 18:18:22

Joer...
La primera opción a simple vista se ve muy buena, aún a pesar de que tarde tiempo...
la Opción de UDP, también la veo muy interesante, pero le veo el inconveniente de tener que tener (valga la redundancia) un programa a la escucha solamente para ese cometido, dado que esa circunstancia se produce muy de cuando en cuando...
Casi voy a experimentar con la primera....

Caral 07-02-2007 18:29:47

Hola
Dos preguntas tontas:
1-El servidor no genera una ip al equipo de red.?
2-Veo que trabaja con ip, como mysql, en Firebird no se coloca la direccion ip en algun componente directamente, como es el caso de zeos para mysql.?
Disculpen la intromision, pero me parecio muy interesante el tema.
Saludos

seoane 07-02-2007 18:35:26

Hola Caral, el problema aquí es que cuando esta creando el programa no sabes la ip que va a tener el servidor, pues en cada empresa donde instales tu aplicación pueden tener una configuración de la red diferente. En una el servidor puede ser 10.10.1.3 y en otra 192.68.1.33, como ves ni siquiera están dentro del mismo rango de ips. Esto se soluciona pidiendo la ip del servidor al configurar el cliente, pero en el caso de Ardilla parece que el cliente es un vago, y se busca que el cliente se configure solo.

Caral 07-02-2007 19:07:10

Hola Seoane
Otra pregunta:
Como sabes utilizo un archivo .ini en mi programa para que busque la base de datos, crees que seria una opcion en este caso, se podria hacer algo para que modificando solamente este archivo (como es mi caso), el cliente pudiera encontrar la direccion ip., o se complica?
Por otro lado si lograis hacer el programa de enlace, lo pondriais por aqui?
Saludos

seoane 07-02-2007 19:29:10

Por supuesto Caral, la idea del ini esta muy bien, pero sigue siendo necesario que al menos la primera vez alguien nos indique la dirección del servidor para que así podamos guardarla en el ini. Con la rutina que el sugiere el propio programa busca la ip del servidor, luego puede guardarla en un ini para utilizarla en otras ocasiones.

egostar 07-02-2007 19:41:37

Y no seria mejor en lugar de utilizar las direcciones IP solo el nombre del servidor, yo casi nunca uso la IP de un servidor porque es un lio si cambia constantemente.

Saludos.

Edito: He visto que se usa mucho las IP cuando quieren configurar una base de datos y hace \\192.168.1.217\D:\......., yo hago mejor esto \\MOVIL\D:\........ y no tengo ningun problema si cambia la IP.

ArdiIIa 07-02-2007 20:36:26

Cita:

Empezado por seoane
El tema parece interesante. :)
Otra posible solución es utilizar UDP.
broadcast

Al final me he decantado por esta opción, resulta la más fácil y completa.
De paso, seguro que lo aprovecho y a consta de esta tontería les monto un sistema de mensajería interna...
"JEFE "ven aquí"--->SECRETARIA "ya voy" ---> JEFE

Además lo voy a montar en el mismo programa, sin necesidad de otro que escuche... Como en la máquina donde está la BD siempre utilizan el programa en modo local, será este el que se encargue de decir a los demás, donde está la BD, la respuesta de éste, será "Host:Unidad:\Ruta....\Base de Datos.Gdb".
Únicamente tendré que explicarles que para que esto funcione, el programa donde se encuentra la BD tendrá que estar en ejecución... Creo que tampoco es mucho pedirles a cambio de lo que van a obtener con simplemente pulsar un botoncito de nada...
Ya estoy haciendo pruebas con los UDP y funcionan de maravilla, veremos que tal se comportan cuando esté en la red... Por añadidura, espero no tener que pegarme con FireWalls y cosas así...
Gracias Domingo por tu planteamiento tan efectivo ...

Caral 07-02-2007 21:57:49

Hola
Espero nos pase ArdiIIa el codigo pare ver como trabaja, siempre y cuando seoane no lo haga antes, esto (UDP) me tiene intrigado.
Saludos

ArdiIIa 07-02-2007 22:00:41

Cita:

Empezado por Caral
Hola
Espero nos pase ArdiIIa el codigo pare ver como trabaja, siempre y cuando seoane no lo haga antes, esto (UDP) me tiene intrigado.
Saludos

Claro que si. Ahora estoy haciendo pruebas y adaptándolo todo, está cociéndose.. cuando lo tenga cocinado aquí estará.
De todas formas, me queda ver su comportamiento en red... y eso lo veré mañana...

ArdiIIa 08-02-2007 00:37:21

En pruebas...
 
Bueno Caral, espero que no me sometas a un tercer grado.... Vamos a ver los pasos que he seguido hasta ahora...

En el FormMain meto este componente
Código Delphi [-]
IdUDPServer: TIdUDPServer
  BufferSize = 4028
  BroadcastEnabled = True
  Bindings = <>
  DefaultPort = Tupuerto8080
  OnUDPRead = IdUDPServerUDPRead
  Left = 628
  Top = 64
end

En el FormMain lo activo o no, dependiendo si es el caso, dado que como es el mismo programa para todas las máquinas, no todas han de actuar como servidores de esta informaón


Código Delphi [-]
procedure TFormMain.FormShow(Sender: TObject);
begin
LoadOptions;
IdUDPServer.Active := Unit_Opciones.Servidor;
blablabla....
end;


Resultando que si ha sido el caso, esta máquina se pone como servidora UDP
y en el evento UDPRead, debemos atender las peticiones de los clientes...
Código Delphi [-]
procedure TFormMain.IdUDPServerUDPRead(Sender: TObject; AData: TStream;  ABinding: TIdSocketHandle);
var
 str:string;
 DataStringStream: TStringStream;
 Mensaje:String;
begin
try
DataStringStream := TStringStream.Create('');
DataStringStream.CopyFrom(AData, AData.Size);
str:='';
str:=DataStringStream.DataString;
If Pos(FormMain.HostName,DataModule1.IBDatabase1.DatabaseName) <> 0 then
Mensaje := DataModule1.IBDatabase1.DatabaseName
else
Mensaje := HostName + ':' + DataModule1.IBDatabase1.DatabaseName;


if str='$Database_Path$' then
    Abinding.SendTo(Abinding.PeerIp,Abinding.PeerPort,Mensaje[1],Length(Mensaje));
finally
 DataStringStream.Free;
end;

end;

En este procedimiento lo que hago es primero obtener la ubicación de la base de datos con las comprobaciones pertinentes... con respecto a la base de datos y nombre de la máquina.
También pregunto "if str='$Database_Path$' then" esto es la cadena que se espera del cliente que pide la información. Fijate que en este caso, se podrían controlar diversas cadenas y por supuesto devolver diversa información... Que era lo que comentaba seoane.

Bueno pues si los pasos se cumplen, respondemos con el socket recibido en el evento...
Código Delphi [-]
Abinding.SendTo(Abinding.PeerIp,Abinding.PeerPort,Mensaje[1],Length(Mensaje));
y la fase servidor ya está terminada.

En este paso, ahora mismo, me surge la duda de como le envío el nombre de la máquina y el path completo de la BD, no se si este debe ir tal cual o con dobles barras
Ejp: "edu:d:\\data\\mybase.fdb"



Ahora vamos con el cliente.... El problema surgen porque no saben o no quieren configurar el path de la BD, que tal como dije antes, es configurable desde el módulo de configuración del programa y en este paso procedemos así:

En el Form de configuración introducimos un:
Código Delphi [-]
IdUDPClient: TIdUDPClient
  BufferSize = 4028
  BroadcastEnabled = True
  Port = Tupuerto8080
  Left = 292
  Top = 152
end

Especial importancia en la propiedad "BroadcastEnabled = True" que era lo que comentaba seoane, de este modo nos aseguramos que el mensaje se difunda por toda la red... (todavía no probado).

También el el form de configuración he puesto dos botones
"autoconfigurar" y "cancelar autonconfigurar".

cuando pulsamos auto configurar hacemos esto:

Código Delphi [-]
procedure TFormConfig.ButtonAutoConfigClick(Sender: TObject);
Var cTemp : String;
begin
Autoconfig := True;
ButtonAutoConfig.Enabled := False;
ButtonCancelarAuto.Enabled := True;
IdUDPClient.Broadcast('$Database_Path$',Tupuerto8080);

cTemp := '';
while (cTemp = '') and Autoconfig DO
Begin
  cTemp := IdUDPClient.ReceiveString(3);
  Application.ProcessMessages;
End;
AutoConfig := False;
ButtonAutoConfig.Enabled := True;
Button1.Enabled := False;
if Trim(cTemp) <> '' then
Begin
  FilenameEdit1.FileName := cTemp;
  FilenameEdit1.Refresh;
  ButtonTestClick(Sender);
  End;
end;

Que lo que hace es difundir el mensaje "IdUDPClient.Broadcast('$Database_Path$',Tupuerto8080);" y esperar a recibir respuesta en el bucle... En el caso de no querer esperar, damos al botón CancelarAutoconfig, que es el que cambia el estado de la variable Autoconfig y detiene el bucle.
En el caso de que hayamos recibido una respuesta, la procesamos asignando el valor que hemos recibido del "servidor" y ya de paso, hacemos un click en el botón que realiza un test de conexión, para verificar que el parámetro obtenido es el correcto.


También he montado un checkbox en el módulo config, para que exista al menos una máquina servidora y que también hace alguna verificación para evitar que haya más de una máquina como servidor...
Código Delphi [-]
procedure TFormConfig.CheckBoxServidorClick(Sender: TObject);
begin
CheckBoxServidor.OnClick := NIL;
If Pos(FormMain.HostName,DataModule1.IBDatabase1.DatabaseName) <> 0 then
Begin
  FormMain.Aviso('ESTE ORDENADOR NO PUEDE ESTABLECERSE COMO SERVIDOR' );
  CheckBoxServidor.Checked := False;
End;
 OptionsChange(Sender);
 CheckBoxServidor.OnClick := CheckBoxServidorClick;
end;
Y esto es todo... de momento... lo he probado en local y aparentemente funciona. Mañana veré si pasa la prueba de fuego

jlrbotella 08-02-2007 10:15:30

Cambios de máquina
 
Una buena solución si teneís un windows server, es configurar el dhcp para que le asigne la ip, así como los dns que correspondan.

En los dns puedes asignarle un alias donde este tu máquina servidor, y en los pc's cliente los llamas por el alias, y el nº de puerto.

Saludos,
JL

ArdiIIa 08-02-2007 15:08:35

Bueno, pues hemos pasado la prueba de momento...
El procedimiento funciona a la perfección, desde máquinas clientes se pregunta al servidor y este devuelve correctamente el path de la BD...
Eso sí, en alguna máquina con firewall ha habido problemillas (salvables)...
Esta tarde continuaremos con más máquinas.
Lo bueno de este sistema es que lo ha realizado "la secretaria", no ha hecho falta ningún "genio" de mantenimiento, y yo me he ahorrado 100 km de viaje...

Lepe 09-02-2007 12:50:27

Cita:

y yo me he ahorrado 100 km de viaje..
¡¡ Chico, pero si en eso es donde se saca más beneficio !! :D :D

PD: Coincido plenamente, normalmente tienes más interés en echar esas 2 horas programando o tomando un café, que viajando ;).

Troffed 07-03-2007 19:23:11

Lo acabo de probar dentro de la red y perfecto.

Muchas gracias.

valdorre 14-03-2007 05:14:53

hola, me podrian decir que componente es ese de udp,

cito:
En el FormMain meto este componente
Código Delphi [-]IdUDPServer: TIdUDPServer
BufferSize = 4028
BroadcastEnabled = True
Bindings = <>
DefaultPort = Tupuerto8080
OnUDPRead = IdUDPServerUDPRead
Left = 628
Top = 64
end

como inserto esto en el main
saludos

Osvaldo
[/font]

jlrbotella 14-03-2007 09:33:04

Es un componente de Indy (Pestaña Servers). Mira a ver si lo tienes instalado este paquete. Si no te lo puedes descargar desde: http://www.indyproject.org/Sockets/D...es/Indy10.aspx


La franja horaria es GMT +2. Ahora son las 00:22:35.

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