Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Redes (https://www.clubdelphi.com/foros/forumdisplay.php?f=37)
-   -   Error al conectar Firebird en red (https://www.clubdelphi.com/foros/showthread.php?t=95583)

Angel.Matilla 23-02-2022 10:43:32

Error al conectar Firebird en red
 
Primero que nada decir que pongo esta pregunta aquí porque creo que es donde debe ir. Si los administradores consideran más correcto situarla en otro sitio, adelante.

Hace tiempo pedí ayuda para poder conectar una aplicación hecha en BCB 6 a una base de datos Firebird en red. Me distéis una solución en aquel hilo (Conectar Firebird en red). Voy a explicar lo que estoy haciendo en el programa para conectar a la BB.DD.
1. Los valores de la ruta deacceso los guardo en un fichero ini con estos valores:
Cita:

[DATOS]
Entorno=\\JUANI\DatAfi30
Tablas=JUANI/3050:C:\DatAfi30\Tablas
Seguridad=C:\Users\Usuario\Documents\Copia Seguridad
y lo leo, sobre las variables previamente definidas tipo char, con la típica instrucción:
Código:

GetPrivateProfileString("DATOS", "Entorno"  , "C:\\DatAfi30\\"      , cEntorno  , sizeof(cEntorno)  , (ExtractFilePath(Application->ExeName) + "PtoDat30.ini").c_str());
GetPrivateProfileString("DATOS", "Tablas"  , "C:\\DatAfi30\\Tablas", cTablas  , sizeof(cTablas)  , (ExtractFilePath(Application->ExeName) + "PtoDat30.ini").c_str());
GetPrivateProfileString("DATOS", "Seguridad", ""                    , cSeguridad, sizeof(cSeguridad), (ExtractFilePath(Application->ExeName) + "PtoDat30.ini").c_str());

Esto he comprobado que lo hace bien y que los valores que recupera son los que están garabados.
2. Asigno el nombre de la BB.DD. en el elemento TIBDatabase.
Código:

fMenu->GesInt->DatabaseName = AnsiString(cTablas) + "GesInt.fdb";
3. Verifico que la base de datos existe:
Código:

bool TInicio::CreaDb()
{
    try
    {
          if (FileExists(AnsiString(cTablas) + "GesInt.fdb"))
              return true;
             
          fForBln->IniBarra("Creando base de datos");
          fMenu->Auxiliar->Transaction->Active = false;
          fMenu->Query->Transaction->Active    = false;
          fMenu->GesInt->Connected            = false;
          fMenu->GesInt->DatabaseName          = AnsiString(cTablas) + "GesInt.fdb";
          fMenu->GesInt->SQLDialect            = 3;
          fMenu->GesInt->Params->Clear();
          fMenu->GesInt->Params->Add("USER 'sysdba'");
          fMenu->GesInt->Params->Add("PASSWORD 'masterkey'");
          fMenu->GesInt->Params->Add("PAGE_SIZE 4096");
          fMenu->GesInt->Params->Add("DEFAULT CHARACTER SET ISO8859_1 COLLATION ES_ES_CI_AI");
          fMenu->GesInt->CreateDatabase();
    }
    catch(Exception &Exc)
    {
          return false;
    }
    return true;
}

Y aquí es donde esta el problema porque al ejecutar el FileExists la aplicación le responde que no existe y trata de ejecutar la creación de dicha BB.DD. en las líneas siguientes, pero como ya existe lógicamente da error.

Hemos comprobado que el puerto 3050 está abierto en ambas máquinas y en desde el equipo cliente se puede ver en el explorador de Windows la BB.DD. en el servidor. He estado mirando cosas por la red sobre conexión de Firebird en red y todas las soluciones apuntan a las sugerencias del hilo que citaba antes.

¿Podéis darme una pista de qué puedo hacer para solucionar este problema?

Angel.Matilla 23-02-2022 11:20:27

Para probar he cambiado el punto de ejecución de ese FileExists al punto justo anterior al que llama a esa función y sigue dando el mismo error.

Casimiro Notevi 23-02-2022 11:37:39

Si Tablas es: C:\\DatAfi30\\Tablas
Y haces fMenu->GesInt->DatabaseName = AnsiString(cTablas) + "GesInt.fdb";
Entonces obtienes: C:\\DatAfi30\\TablasGesInt.fdb

Angel.Matilla 23-02-2022 11:51:06

Cita:

Empezado por Casimiro Notevi (Mensaje 545547)
Si Tablas es: C:\\DatAfi30\\Tablas
Y haces fMenu->GesInt->DatabaseName = AnsiString(cTablas) + "GesInt.fdb";
Entonces obtienes: C:\\DatAfi30\\TablasGesInt.fdb

No; ese C:\\DatAfi30\\Tablas es el valor por defecto. Además luego de leer el valor del ini le añado la barra final (cTablas[AnsiString(cTablas).Length()] = '\\';); sé que es una tontería, pero al escribir el código se me olvidó incluirla en el fichero ini y lo arreglé así. En este caso sería JUANI/3050:C:\\DatAfi30\\Tablas porque está definido así en el ini. No obstante he estado haciendo unas pruebas en mi máquina simulando que es una red, y le puesto en el ini en vez del valor original una dirección de red que queda así:
Cita:

cTablas = DEPAPEL/3050:C:\\DatAfi31\\Tablas\\
fMenu->GesInt->DatabaseName = AnsiString(cTablas) + "GesInt.fdb";
y he comprobado que incluso haciéndolo en local con esta simulación da el mismo error. Me tiene totalmente descolocado porque hasta ayer por la mañana funcionaba a la perfección y no veo que haya modificado nada para que ocurra esto.

Casimiro Notevi 23-02-2022 12:51:05

¿"Juani" es un directorio o un alias?
¿Y si pruebas manualmente, conecta?
192.168.1.100:/ruta/bd.fdb
A ver si tienes firebird desactivado, o han instalado un antivirus o algo en el servidor y está cortando el acceso, o firewall...

Angel.Matilla 23-02-2022 13:41:24

Cita:

Empezado por Casimiro Notevi (Mensaje 545550)
¿"Juani" es un directorio o un alias?

Es el nombre de la máquina
Cita:

¿Y si pruebas manualmente, conecta?
192.168.1.100:/ruta/bd.fdb
A ver si tienes firebird desactivado, o han instalado un antivirus o algo en el servidor y está cortando el acceso, o firewall...
Hace unas semanas tuvieron problemas porque se estropeó el disco duro del servidor y tuvieron que cambiarlo, pero quedó todo funcionando a la perfección después de abrir los puertos en el cliente y en el servidor.

El problema es que hasta ayer por la mañana se conectaba sin problemas. He seguido haciendo pruebas y me he encontrado que si elimino esa comprobación de si existe la BB.DD. funciona a la perfección y arranca sin problemas.

Si encontrara la forma de hacer un log de depuración con alguna librería o algo me ayudaría muchísimo. Sigo investigando.

Casimiro Notevi 23-02-2022 13:47:29

Cita:

Empezado por Angel.Matilla (Mensaje 545555)
... si elimino esa comprobación de si existe la BB.DD. funciona a la perfección y arranca sin problemas..

Es que no puedes hacer un FileExists de otro ordenador salvo que tenga el directorio compartido también.
Y un servidor no debe tener nada compartido. Firebird solamente necesita que esté el puerto 3050 abierto, para que puedan comunicarse por él, nada más.

Angel.Matilla 23-02-2022 17:33:38

Cita:

Vale, me acabas de enseñar una cosa que no sabía.
Mas que no sabía es que no se me había ocurrido: si la carpeta no se "ve" desde el cliente no se puede comprobar la existencia de un fichero en ella.

juanelo 23-02-2022 17:44:55

Que tal,
A mi me parece mas que va por la exclusividad que tiene el proceso de FBServer para con el archivo fisico (FDB) y este no le concede "permiso" a otro proceso para tener alguna operacion con el archivo.

Casimiro Notevi 23-02-2022 17:48:09

Es que el servidor de BD debe ser "cerrado", nadie debe tener acceso a él, la única "puerta abierta" es el puerto 3050 (en este caso) para que pueda recibir peticiones. El cliente pide, el servidor responde.
Pero un programa cliente (o programas cliente en distintos ordenadores) no debe tener acceso al servidor, y mucho menos crear una base de datos allí. El servidor debe tratarse como una fortaleza inexpugnable. Los clientes no pueden conectarse, ver lo que hay, crear bases de datos, borrarlas, etc. todo eso es un gran peligro.
En tu caso, supongo que en el servidor se está ejecutando el programa, y en los terminales se está ejecutando un acceso directo al mismo.

Si tu programa lo hace, aunque no es un buen método, y tienes implementada esas opciones, tal vez el problema sea de permisos, por eso antes podía y ahora no.

Angel.Matilla 23-02-2022 17:49:59

Cita:

Empezado por juanelo (Mensaje 545562)
Que tal,
A mi me parece mas que va por la exclusividad que tiene el proceso de FBServer para con el archivo fisico (FDB) y este no le concede "permiso" a otro proceso para tener alguna operacion con el archivo.

Al margen de que por error he borrado mi contestación anterior, tu sugerencia es buena pero si esa exclusividad estuviera presente no permitiría ningún tipo de acción sin los permisos pertinentes, que están concedidos. El problema reside en que antes, con el mismo código, funcionaba bien y ahora no y me estoy volviendo loco tratando de averiguar el por qué.

Casimiro Notevi 23-02-2022 17:50:34

Cita:

Empezado por Angel.Matilla (Mensaje 545561)
Mas que no sabía es que no se me había ocurrido: si la carpeta no se "ve" desde el cliente no se puede comprobar la existencia de un fichero en ella.

Claro que no, no es su cometido, pero si lo haces así, bueno, pues vale, ya depende de ti y los requesitos que necesites para mantenerlo así o cambiarlo :)

Casimiro Notevi 23-02-2022 17:51:40

Cita:

Empezado por juanelo (Mensaje 545562)
Que tal,
A mi me parece mas que va por la exclusividad que tiene el proceso de FBServer para con el archivo fisico (FDB) y este no le concede "permiso" a otro proceso para tener alguna operacion con el archivo.

No recuerdo ahora mismo que exista ningún tipo de exclusividad.

Angel.Matilla 23-02-2022 19:12:14

Cita:

Empezado por Casimiro Notevi (Mensaje 545567)
Claro que no, no es su cometido, pero si lo haces así, bueno, pues vale, ya depende de ti y los requesitos que necesites para mantenerlo así o cambiarlo :)

Una pregunta, que estaba en el mensjae que he borrado antes por error: ¿Cómo hacéis en una instalación de red para comprobar si existe la BB.DD. o un fichero?

Casimiro Notevi 23-02-2022 19:22:51

Cita:

Empezado por Angel.Matilla (Mensaje 545570)
Una pregunta, que estaba en el mensjae que he borrado antes por error: ¿Cómo hacéis en una instalación de red para comprobar si existe la BB.DD. o un fichero?

Nada, los programas clientes no tienen que comprobar si existe algo en un servidor. Los programas clientes sólo hacen peticiones al servidor y éste contesta, nada más.
No es desempeño de un programa cliente mirar qué hay en un servidor.
Los programas clientes conectan a la dirección que le han dado, nada más, y si no conecta deberán revisar el servidor qué problema tiene.
Es como si tú entras a una página web y te dice que no puede conectar, tú no puedes desde tu navegador cliente mirar si está algún fichero o la BD en el servidor web.

Angel.Matilla 23-02-2022 19:38:18

Gracias. No me lo había planteado así porque la misma aplicación es la que uso pera el servidor y los clientes. Tengo que replantear la forma de conectarse los equipos.

De todas maneras me está ocurriendo una cosa muy curiosa: Si uso el código tal como lo tengo ahora:
Código:

GetPrivateProfileString("DATOS", "Entorno", "C:\\DatAfi30\\", cEntorno, sizeof(cEntorno), (ExtractFilePath(Application->ExeName) + "PtoDat30.ini").c_str());
if (!FileExists(AnsiString(cEntorno) + "Tablas\\GesInt.fdb"))
etc.

donde la variable cEntorno tiene el valor para la aplicación, una vez leída, \\\\Depapel\\c\\DatAfi30\\ hace el mismo efecto incorrecto. Pero si pongo la dirección a pedal:
Código:

if ("\\\\Depapel\\c\\DatAfi30\\Tablas\\GesInt.fdb"))
etc.

¡Funciona bien! Cada vez lo entiendo menos.

Casimiro Notevi 23-02-2022 19:44:31

Hecha un vistazo a esto, es que con tantas barras y demás me parece un poco engorroso. Estoy habituado a servidores linux, algo así: 192.168.1.100:/datos/labasedatos.fdb

Casimiro Notevi 23-02-2022 20:05:21

Cita:

Empezado por Angel.Matilla (Mensaje 545572)
la misma aplicación es la que uso pera el servidor y los clientes.

Incluso así, tampoco debes permitirlo. Solamente conectar a la BD y hacer peticiones, nada más.
La diferencia si está en el servidor es que la ruta será localhost:/dondesea/basedatos.fdb

Angel.Matilla 24-02-2022 09:43:55

Tienes razón. Por eso digo que conservo demasiados vicios de mi época de programar en Clipper. Muchas gracias por toda la información. Me ha sido muy útil.

cloayza 02-03-2022 21:11:38

Estimado Angel.Matilla, si me lo permite quisiera plantear otro punto de vista.

Creo que es muy practivo el uso de alias para indicar la base de datos de conexión, nos permite flexibilizar a que bases de datos nos conectaremos sin hacer mayores cambios a archivos de configuración...

Para ello basta definir los alias a las base de datos en el archivo "Aliases.conf", ubicado en carpeta de instalacipón de firebird...

Como ejemplo en

Cita:

c:\Program Files\Firebird\Firebird_2_5\Aliases.Conf
Este contiene lo que sigue

Cita:

#
# List of known database aliases
# ------------------------------
#
# Examples:
#
# dummy = c:\data\dummy.fdb

#Aliasname=C:\Ruta\Base\Datos\Firebird

GesInt=C:\DatAfi30\Tablas\GesInt.fdb

#
Luego para la conexión sería:
Cita:

JUANI/3050:GesInt
Si require que el alias apunte a otra base de datos solo modifica la ruta y archivo de base de datos

Saludos cordiales


La franja horaria es GMT +2. Ahora son las 08:50:01.

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