Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Recibir respuesta de un servidor (https://www.clubdelphi.com/foros/showthread.php?t=93904)

NEG1414 02-05-2019 13:31:50

Recibir respuesta de un servidor
 
Buenas..

Tengo un servidor externo en el que en su carpeta "ftp" hay un listado de nombres. Desde mi aplicación el usuario comprobará si su nombre figura en la lista, este paso lo hago accediendo desde la aplicación a a un archivo php que comprueba si el nombre existe o NO.
Mi intención es que una vez una vez obtenido el resultado (si/no) este sea enviado desde el servidor a la aplicacion (¿es posible?).

Una solución que se me ocurre es guardar el resultado en el servidor, desde la Aplicacion volver a conectar con el servidor despues de un tiempo "prudencial" y obtener el resultado; a esta solución le veo el inconveniente de que accedo al servidor por segunda vez sin saber si el algoritmo PHP ya ha hecho la comprobación.

Gracias.

Casimiro Notevi 02-05-2019 15:34:40

Es una pregunta muy genérica, danos más detalles.

dec 02-05-2019 17:10:18

Hola a todos,

En efecto, probablemente, hagan falta más detalles. Tratando de responder a tu pregunta en concreto, cuando tú "llamas" al archivo PHP de tu servidor, este ya te ofrece una respuesta, precisamente, a tu "llamada". Es decir, con un componente "IdHttp", por ejemplo, realizas una petición HTTP al servidor sobre el archivo PHP que necesites. En dicho archivo compruebas si el nombre del usuario está en la lista (este nombre se lo has podido mandar tú desde tu programa al servidor, como un argumento de la petición HTTP, sea GET, sea POST), y, acto seguido, desde el mismo "script" PHP, ya puedes proporcionar una respuesta a la app, que puede ser un texto tal que "existe", o "no-existe", por ejemplo. Tu programa sabrá qué hacer a partir de cualquier de estas respuestas...

dec 02-05-2019 17:18:33

Hola de nuevo a todos,

Aquí lo que podría ser un ejemplo de lo que digo en mi anterior post:

Código Delphi [-]
uses
  // Indy components
  IdURI, IdHttp;

procedure TForm1.Button1Click(Sender: TObject);
var
  Http: TIdHttp;
  URI, Response, User, EncodedUser: string;
begin
  Http := TIdHttp.Create();

  User := 'Nombre de usuario o similar...';

  EncodedUser := TIdURI.URLEncode(User);

  URI := Format('http://www.tu-servidor.com/tu-script.php?usuario=%s',
   [EncodedUser]);

  try
    Response := Http.Get(URI);

    if Response = 'existe' then
    begin
      ShowMessage('El usuario existe, según el servidor');
    end
    else
    begin
      ShowMessage('El usuario NO existe, según el servidor');
    end;

  finally
    Http.Free();
  end;

end;

Creo que más o menos se entiende... al menos eso creo yo. :)

NEG1414 02-05-2019 18:53:54

Buenas.


Muchas gracias por contestar , efectivamente quiza deberia haber dado mas detalles: la llamada al archivo php la hago de la forma:


Código:

HINTERNET sesion = InternetOpen("agent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,0);
const ::HINTERNET handle = ::InternetOpenUrl(sesion,"http://MiServer.es//ComprobarLista.php",NULL,0, INTERNET_FLAG_RELOAD, 0);
InternetCloseHandle(handle);
InternetCloseHandle(sesion);

realmente no utilizo ningun componente Indy :o...


Voy aprobar con los comppnentes indy...


Ahora la duda es cual es la orden que debo de implementar en mi scrip php para que me devuelva el valor "esta" o "no esta"


Gracias Otra Vez.

dec 02-05-2019 19:14:01

Hola a todos,

Ostras... no me dí cuenta de que estábamos hablando de C++ Builder y no de Delphi... pido disculpas. No sé lo que te costaría adaptar el código anterior... supongo que no demasiado, contando además con que los componentes Indy están disponibles, si no me equivoco, en C++ Builder. Aquí parece que pueden ayudarte también a obtener la respuesta del servidor haciendo uso de HINTERNET...

Por otro lado, no sé si se entiende muy bien lo que dices de que no estás seguro del "orden" en el "script" PHP... el "script" será ejecutado cuando realices la petición, y, ya depende del mismo qué respuesta ofrecer, pero, sería tan "sencillo" como esto:

Código PHP:

<?php

if (ComprueboLoQueNecesito()) {

  echo 
'esta';

} else {

  echo 
'no esta';

}

exit;

Lógicamente, en "ComprueboLoQueNecesito" deberás hacer lo que necesites... coger el argumento / nombre enviado en la URL y comprobar si existe o no en el archivo en cuestión, etc. En todo caso la respuesta es tan sencillo como hacer un "echo"... y eso es lo que tú podrás obtener en tu programa: el "echo" del script, en el caso de arriba, o "existe" o "no existe".

NEG1414 02-05-2019 20:32:27

Gracias otra vez



Efectivamente trabajo en c++ builder pero tengo indy9 y los componentes que mencionas deben de estar contenidos en Indy 10.



voy a intentarlo utilizando HINTERNET (gracias por el hipervinculo)



Entiendo que al usar el comando echo en el script php, este enviara el valor obtenido como respuesta (estoy pez en php).





Muchisimas Gracias por tu tiempo

dec 03-05-2019 07:29:03

Hola a todos,

Cita:

Empezado por NEG1414 (Mensaje 531756)
Entiendo que al usar el comando echo en el script php, este enviara el valor obtenido como respuesta (estoy pez en php).

Eso es. Lo que el "script" PHP "muestre" o "escriba" será la respuesta de la petición HTTP a dicho "script". Como se comentó arriba, si observamos el siguiente "script":

Código PHP:

<?php

echo 'Mi respuesta';
exit;

La respuesta será "Mi respuesta", y, acto seguido el "script" termina su ejecución.

NEG1414 05-05-2019 13:13:42

Buenas..


Sigo dandole vueltas a poder recibir una respuesta desde un php a mi aplicacion cb6...


El codigo PHP funciona correctamnete


Código PHP:

<?php
                        
                        
                        $Nombre 
$_GET['Nombre'];

                        
                        
//Se Abre archivo Texto Lista Usuarios
                        
$Lista fopen('ListUsuarios.txt','r');
                    
                        
//Comprobamos si Nombre ya figura en la Lista
                        
$Esta false;
                        while (
$linea fgets($Lista))
                        {
                          if (
$linea===$Nombre )
                            {
                                
$Esta true;
                                
//break;
                            
}            
                        }
                        
                        
fclose($Lista);
                        
                         
//Si no esta en la lista lo incorporamos
                        
if(!$Esta
                        {
                            
$Lista fopen('ListUsuarios.txt','a');    
                            
fwrite($Lista,$NombrePHP_EOL);
                            
fclose($fp);
                        }

                        echo 
$Esta;    

     
?>

</div>

En principio devolveria como respuesta el booleano Esta:confused:.


El codigo en c++ para llamar al scrip y en teoria recibir la respuesta seria..


Código:


  AnsiString NomUsers ="xxxx";

  BYTE  Buffer;
  DWORD BytesRead;

  const ::HINTERNET sesion = InternetOpen("agent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,0);
  if(sesion!=NULL)
  {

    AnsiString Url = "http://xxxxxx.es//GPrUsers//Registrado.php?Nombre="+NomUsers;//?Nombre="+NomUsers;
    const ::HINTERNET handle = ::InternetOpenUrl(sesion,Url.c_str(),NULL,0, INTERNET_FLAG_RELOAD, 0);
    if(handle!=NULL)
    {
        InternetReadFile(handle,&Buffer,sizeof(Byte),&BytesRead);
        //Si Existe
        if(Buffer!=0)
        {
          //EXISTE
        }
        else
        {
          //NO EXISTE
        }
    }
    InternetCloseHandle(handle);
  }
  else
  {

  }
  InternetCloseHandle(sesion);

La llamada la hace correctamente, el problema lo tengo en la respuesta.. mi planteamineto es que el booleano Esta (respuesta) ocupa 8 bits (un byte) y si fuera positivo su valor seria 00000001 y si fuera negativo 00000000, valor que se asignaria a Buffer....
Ya que obviamente estoy equivocado alguien me puede orientar...


Gracias

dec 05-05-2019 13:48:32

Hola a todos,

Ojo con los tipos... si pruebas "echo true;" verás que lo que obtienes es un "1". Y es un "1", es decir, una cadena, no un entero. Por otro lado, si pruebas un "echo false;", verás que no obtienes nada... ni siquiera "0"... Quizás debas tener en cuenta todo esto...

NEG1414 05-05-2019 13:53:57

Gracias por contestar


Entiendo con tu respuesta que el codigo "Post" y "Get" con hinternet es correcto, donde tengo el problema es a la hora de "valorar" la respuesta obtenida en Buffer ...

dec 05-05-2019 14:25:38

Hola a todos,

Cita:

Empezado por NEG1414 (Mensaje 531789)
Gracias por contestar


Entiendo con tu respuesta que el codigo "Post" y "Get" con hinternet es correcto, donde tengo el problema es a la hora de "valorar" la respuesta obtenida en Buffer ...

No... yo sólo me refería a la respuesta... y es porque "if(Buffer!=0)" no me cuadra... puesto que si "$Esta" es "false" no será "0" como acaso esperas... tal vez sería bien una respuesta como "true" y "false", ojo, no valores "booleanos", sino cadenas "true" y "false", y así tendrás que comprobar en tu programa: comparando cadenas, esperando "true" o "false".

NEG1414 05-05-2019 20:41:27

Gracias por contestar,..
He modificado el codigo php de la siguiente manera
Código PHP:

<?php
  $Nombre 
$_GET['Nombre'];
  
//Se Abre archivo Texto Lista Usuarios
  
$Lista fopen('ListUsuarios.txt','r');
  
//Comprobamos si Nombre ya figura en la Lista
  
$Esta 'N'//MODIFICADO
  
while ($linea fgets($Lista))
  {
    if (
$linea===$Nombre)
    {
      
$Esta ='S'//MODIFICADO
      //break;
    
}            
  }
  
fclose($Lista);
  
//Si no esta en la lista lo incorporamos
  
if($Esta=='N'//MODIFICADO
  
{
    
$Lista fopen('ListUsuarios.txt','a');    
    
fwrite($Lista,$Nombre.PHP_EOL);
    
fclose($fp);
  }
  echo 
$Esta;    
?>

y la llamada:

Código:

  char  Buffer;  //MODIFICADO
  DWORD BytesRead=0;

  const ::HINTERNET sesion = InternetOpen("agent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,0);
  if(sesion!=NULL)
  {

    AnsiString Url = "http://XXXXX.es//GPrUsers//Registro.php?Nombre="+NomUsers;
    const ::HINTERNET handle = ::InternetOpenUrl(sesion,Url.c_str(),NULL,0, INTERNET_FLAG_RELOAD, 0);
    if(handle!=NULL)
    {
        InternetReadFile(handle,&Buffer,sizeof(Byte),&BytesRead);
        //Si  Existe
      if(Buffer=='S')//MODIFICADO
        {
     
        }
        else
        {
       
        }
    }
    InternetCloseHandle(handle);
  }

Y buffer sigue teniendo valor NULL '/n'
,¿Que estoy haciendo mal?

Gracias

Casimiro Notevi 06-05-2019 01:47:30

Recuerda que tienes la opción de integrar código mediante las etiquetas, también para php, no es necesario que pierdas el tiempo poniendo colores y demás.



Ñuño Martínez 06-05-2019 11:44:57

Yo creo que hay algo que no funciona como esperas y hay un error en alguna parte. Por eso, yo haría lo siguiente:

Primero, revisaría la configuración del servidor para asegurarme de que devuelve todos los errores que se puedan producir. Es decir, lo pondría en modo pruebas. Que no ignore absolutamente nada. Ojo, que PHP es muy puñetero y la gestión de los errores está repartida en unas cuantas variables, y si no todas están bien asignadas habrá cosas que no verás. Asegúrate, también, de que no cambias alguna de estas variables en tiempo de ejecución. Si no lo has hecho ya, lee todo esto.

Luego cambiaría el código del cliente para que muestre todo lo que devuelva el servidor, sin dejar ni un octeto. Supongo que InternetReadFile es capaz de indicar si ha quedado algo en la caché. Pues eso, que llene un TMemo o un archivo de disco con lo que reciba, tal cual. Cuidado con los caracteres de control (saltos de línea, tabuladores, etc.). También guardaría la información de cabecera, porque puede dar información invisible pero útil, como la codificación de caracteres, la URI auténtica, variables GET y POST, huellas (cookies),...

A partir de ahí ya se verá lo que se hace.

NEG1414 06-05-2019 20:17:56

Buenas...


Gracias por contestar a todos... dec estabas en lo cierto , realmente echo $Esta devuelve una cadena, el error lo cometia yo al no leerla completamente mediante un while.




Código:

        while (InternetReadFile(handle,&Buffer,sizeof(Buffer),&BytesRead))
        {
          if(BytesRead==0){break;}
        }

Una vez lee todos los bytes y sale del bucle while, el valor d Buffer es S o N.


Gracias otra vez.


La franja horaria es GMT +2. Ahora son las 16:29:34.

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