5. EJEMPLO DE DISEÑO E IMPLEMENTACIÓN BAJO

UN ENTORNO DE PROGRAMACIÓN VISUAL (C++ BUILDER):

En este apartado mostraremos una aproximación a la implementación del cliente FTP , a partir del lenguaje C++ , en concreto utilizando el paquete C++ Builder versión 3.0

Utilizaremos el control de FTP , que nos proporciona el paquete de Fastnet , que podemos añadir al C++ Builder. El próposito del control TNMFTP, que nos proporciona el paquete FastNet 4.00 de NetMaster, es el de transferir ficheros desde y hacia un servidor FTP. El uso de este componente requiere la pila de 32 bits TCP/IP , WSOCK32.DLL.

 

 

 

Ventana del Interfaz de Usuario del compilador C++ Builder,

donde aparece en la paleta superior el control NMFTP que utilizaremos durante este ejemplo.

 

En el entorno visual de programación con el que vamos a trabajar , lo haremos con componentes , que son objetos definidos como clases que realizan alguna función predefinida y que se componen de los siguientes elementos :

 

 

5.1 EL CONTROL TNMFTP : Como todo control en los entornos de programación visual por eventos dispone de una serie de caracteristicas que son las propiedades , métodos y por supuesto eventos. Seguidamente se hace detalle de los pertenecientes al control en cuestión.

5.1.1 Propiedades :

- Host : Nombre o dirección IP del host al que nos queremos conectar.

- Port : 21 , predeterminado . Se puede modificar para utilizar otro numero de puerto no estandar.

- LocalIP : Contiene la dirección IP del host local , si dispone de más de una ,solo se especifica la primera.

- RemoteIP : Contiene la dirección IP del servidor remoto de la conexión actual.

- UserID : Identificador de Usuario , va a ser una cadena del tipo AnsiString.

- Password : La contraseña del Usuario . (AnsiString)

- TransactionReply : Donde obtenemos la respuesta del servidor de la última operación que hemos realizado. (AnsiString).

- ReplyNumber : Contiene el resultado de una transferencia con el servidor remoto expresado en un código de tres cifras.

- CurrentDir : Directorio Actual en el sistema remoto. (AnsiString).

- BytesRecvd (int) : Entero que nos devuelve el número de bytes recibidos. Combinado con la propiedad BytesTotal y el evento OnPacketRecvd podemos controlar el progreso de la transferencia.

- BytesTotal (int) : Una propiedad de sólo lectura que representa el número total de bytes que se transfieren. Junto con la propiedad BytesRecvd o BytesSent y los eventos OnPacketRecvd o OnPacketSent , podemos controlar el progreso de la transferencia.

- BytesSent (int) : Entero que nos devuelve el número de bytes enviados. Combinado con la propiedad BytesTotal y el evento OnPacketRecvd podemos controlar el progreso de la transferencia.

- Status : Contiene el ultimo mensaje de estado que fue pasado como parámetro en el evento OnStatus.

- ReportLevel : Especifica el detalle de los mensajes de estado devueltos por la propiedad Status y el evento OnStatus.

- TimeOut : Especifica la cantidad de tiempo en milisegundos a esperar una respuesta del socket . Si se sobrepasa se cierra la conexión. Default: 0

- Proxy : Contendrá el nombre o la direción IP de un servidor proxy si el acceso es via proxy.

- ProxyPort : Contendrá el número de puerto a utilizar por el servidor proxy, caso de que se utilice uno.

- WSAInfo : Contendrá información sobre la versión actual de Winsock que se esté utilizando.

 

5.1.2 Métodos :

- Connect ( ), Disconnect ( ) : Conexión y desconexión al servidor ftp respectivamente.

- List ( ) : Se utiliza para listar el contenido de un directorio , nos generará un evento OnListItem por cada línea del listado.

- Nlist ( ) : Idem a la anterior , con la excepción de que aquí sólo nos aparecerán los nombres de los ficheros o directorios sin ninguna información adicional.

- Mode (modo) : Existen dos tipos de modos de transferencia : MODE_ASCII ó MODE_IMAGE

- Allocate (TamañoFichero) : Este método es necesario en ciertos sistemas de archivos para reservar el espacio necesario para almacenar los archivos.

- Download (fichero_remoto, fichero_local) : Trae el fichero remoto especificado como primer parámetro y lo almacena en el host local con el nombre del segundo parámetro.

-DownloadRestore(fichero-remoto, fichero-local) : Continua con una operación de descarga del servidor remoto a nuestro ordenador, que fue interrumpida con anterioridad. Así el primer parametro donde se le especifica el fichero remoto , es el fichero a continuar copiando del servidor y el fichero local es donde teniamos la copia parcial hasta que se produjo la interrupción en la descarga.

- Upload (fichero_local, fichero_remoto) : Se encarga de subir al servidor el fichero local especificado en el primer parámetro y almacenarlo en el mismo, con el nombre del segundo parámetro que se le pasa.

 

 

- UploadAppend (fichero_local, fichero_remoto) : Se encarga de subir al servidor el fichero local especificado en el primer parámetro y almacenarlo en el mismo con el nombre del segundo parámetro que se le pasa, en el caso de que este último exista se añadirá al final del fichero remoto.

- UploadRestore (ficherol_local, fichero_remoto, Posicion) : Restaurará una operación de subida de datos al servidor que con anterioridad fue interrumpida. Para ello se pasa tambien el parametro posición , a partir de la cual se restaurará el fichero remoto.

 

-UploadUnique (ficherol_local) : Se encarga de subir al servidor el fichero local especificado en el primer parámetro y almacenarlo en el mismo con el nombre si existe en el servidor remoto.

 

- Delete (nombreFichero) : Borra el fichero que se le pasa como parámetro.

 

- Rename (nombrefichero,nombrefichero2): Renombra el fichero remoto que se le pasa como parámetro, con el nombre que se le pasa como segundo parámetro.

 

- ChangeDir (directorio) : Cambia al directorio que se le pasa como parámetro.

 

- Abort ( ) Cancela una operación de transferencia en progreso.

 

- MakeDirectory (directorio) : Crea un nuevo directorio con el nombre que le hemos pasado como parámetro.

 

- RemoveDir (directorio) : Borra el directorio que se especifica.

 

- ReInitialize : Reinicializa la conexión FTP al estado de la fase del login.

 

- DoCommand (orden) : Se utiliza para lanzar cualquier orden standard del protocolo FTP.

 

 

 

 

 

 

5.1.3 Eventos :

 

- OnSuccess : Se produce tal evento si una orden termina correctamente. Como parámetro recibiremos la orden.

- OnAuthenticationFailed : Se da cuando el servidor FTP nos pregunta el identificador de usuario (UserID) y el password para el login, y uno de los dos no se le ha facilitado o es inválido.

- OnConnect : Se da cuando el cliente se conecta con el servidor.

- OnConnectionFailed : Se da cuando la orden connect no ha tenido éxito.

- OnConnectionRequired : Se da cuando en la llamada a un método se necesita que el cliente esté conectado con el servidor FTP.

- OnDisconnect : Este evento se produce cuando el cliente se desconecta del servidor.

- OnListItem : Este evento se da cuando se recibe un nuevo elemento de una orden List. Se recibe como parámetro un AnsiString con la linea.

- OnPacketRecvd : Se da cada vez que recibimos un paquete. Se utiliza para controlar el progreso de la transferencia.

- OnPacketSent : Se da cada vez que enviamos un paquete. Se utiliza para controlar el progreso de la transferencia.

- OnFailure : Se produce en el caso de que una órden termine con error.

- OnError : Se da cuando el servidor nos devuelve un mensaje de error. La información sobre el error se pasa con el parámetro ErrNo como un número y el parámetro Errmsg como un string.

- OnHostResolved : Se da cuando la dirección del host remoto se ha resuelto. En el caso de que el host remoto sea inválido se producirá un evento OnInvalidHost.

- OnInvalidHost : Se da cuando la propiedad Host contiene un nombre de host inválido.

- OnStatus : Se da cada vez que un mensaje de estado es devuelto por el servidor o el estado del control cambia. También se modifica la propiedad Status para reflejar ese cambio de estado.

- OnTransactionStart : Se da al principio de una transferencia de datos, ya sea de ficheros o un listado de directorio.

- OnTransactionStop : Se produce al final de una transferencia de datos.

- OnUnSupportedFunction : Se produce cuando un servidor no soporta cierto comando que se le ha pasado. El comando en cuestión puede determinarse estudiando el evento OnFailure y comprobando el parámetro Cmd_Type.

 

 

 

5.2 Trabajando con el Control TNMFTP :

Lo primero para poder transferir ficheros a través del control TNMFTP, es conectarse a un servidor FTP. Esto se consigue dándole los datos del servidor a las propiedades antes vistas de Host y Port. Después le debemos facilitar el identificador de usuario (UserID) y Password. Una vez que le hemos pasado estos datos ya podemos llamar al método Connect para proceder a la conexión con el servidor.

 

Ej :

void __fastcall TForm1::Button1Click(TObject *Sender)

{

NMFTP1->ReportLevel = Status_Basic;

NMFTP1->Host = HostTxt->Text;

NMFTP1->Port = StrToInt(PortTxt->Text);

NMFTP1->UserID = UserTxt->Text;

NMFTP1->Password = PassTxt->Text;

NMFTP1->Connect();

}

 

Una vez ya estamos conectados al servidor , podemos realizar un listado del directorio donde nos encontremos, llamando a los métodos List ó Nlist e implementando un manejador de eventos para el evento OnListItem. Ej :

 

void_fastcall Tform1::NMFTP1ListItem (AnsiString Listing)

{

Memo1->Lines->Add(Listing);

}

Este código vuelca el listado del directorio sobre un Memo.

También podemos cambiar a otro directorio llamando al método ChangeDir , pasandole como parámetro un directorio válido al que deseemos cambiar.

{

NMFTP1->ChangeDir("programs");

}

 

 

 

Para subir ficheros al directorio actual dentro del host remoto, utilizaremos el método Upload. Especificamos como primer parámetro el fichero local y como segundo el remoto.

Ej :

{

NMFTP1->Upload("c:\programs\fichero.zip", "fichero.zip");

}

 

 

Para bajarnos ficheros desde el host remoto a nuestro sistema, una vez seleccionado el fichero deseado, llamaremos al método Download. Especificaremos como primer parámetro el fichero remoto y como segundo el fichero local en el que se va a guardar.

Ej :

{

NMFTP1->Mode(MODE_IMAGE);

NMFTP1->Download("fichero.zip", "c:\download\fichero.zip");

}

En este ejemplo también hemos utilizado el método Mode , para cambiar el tipo de transferencia a binario.

 

 

 

 

 

Un ejemplo del método DoCommand , podría ser utilizando la orden SYST , que nos permite verificar el tipo de servidor ftp al que nos conectamos.

 

Ej :

{

NMFTP1->DoCommand("SYST");

ShowMessage(NMFTP1->TransactionReply);

}

 

 

En el caso de que queramos verificar si se trata de un servidor NT :

 

{

NMFTP1->DoCommand("SYST");

winnt= NMFTP1->TransactionReply.AnsiPos("Windows_NT");

}

 

Si se recibe un 1 en la variable winnt , el servidor es NT.

 

 

 

 

5.3 Aplicación ejemplo , ClienteFTP :

La interfaz de usuario de la aplicación con la que el cliente podrá interactuar para

utilizar el servicio FTP , es la que aparece en las siguientes pantallas :

 

 

En esta primera pestaña de la aplicación es donde se encuentra la información relevante al acceso al servicio , así como el seguimiento de los eventos que tienen lugar durante el proceso de conexión y transferencia.

Disponemos de los campos Host , Usuario y Contraseña donde especificaremos el nombre del servidor al que nos queremos conectar, nuestro identificador de usuario y el password o contraseña que tengamos. Bien hay que decir que podemos utilizar el usuario anonymous y como contraseña nuestra dirección electrónica , siempre y cuando el servidor acepte conexiones anónimas.

El puerto se presupone que es el 21 , puerto bien conocido para el servicio FTP. También disponemos de un pequeño recuadro donde se nos da la posibilidad de especificar Proxy y puerto a utilizar.

 

 

 

 

En la siguiente pestaña disponemos de los mecanismos necesarios para el mantenimiento de ficheros y directorios :

 

Como podemos ver en el panel superior disponemos de los botones para el cambio de directorio , creación de nuevos y eliminación de directorios.

En el siguiente panel tenemos las posibilidades de cambiar de nombre un fichero remoto y de la eliminación de un fichero determinado.

En la parte inferior de la pantalla se ha introducido un control ListView para obtener en modo gráfico un listado del contenido de los directorios del servidor FTP.

 

En la última pestaña de la aplicación disponemos de los procesos para enviar y bajar ficheros del servidor,

con los diferentes métodos que el control TNMFTP nos permite :

 

 

En el primer panel disponemos de la parte de envio de un fichero al servidor FTP , con

los diferentes métodos de Upload , UploadRestore y UploadUnique, explicados

con anterioridad en este mismo capitulo.

Mientras que en el panel inferior tenemos los dos métodos utilizados para la descarga de un fichero desde el servidor : Download y DownloadRestore.

 

5.4 Listado fuente de la aplicación ClienteFTP :

(Unit1.cpp)

 

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Unit1.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

// Evento OnClick del Boton Conectar

void __fastcall TForm1::Button1Click(TObject *Sender)

{

if (CheckBox1->Checked)

/* Si esta activado utiliza los parametros del

Proxy que le asignemos */

{

NMFTP1->Proxy = Edit6->Text;

NMFTP1->Proxy = StrToInt(Edit7->Text);

}

/* Se le pasan al control los parametros del Host ,

Puerto (que en este caso será el 21) ,

Identificador de Usuario y Contraseña */

 

NMFTP1->Host = HostTxt->Text;

NMFTP1->Port = StrToInt(PortTxt->Text);

NMFTP1->UserID = UserTxt->Text;

NMFTP1->Password = PassTxt->Text;

 

// Llamada al metodo Connect()

 

NMFTP1->Connect();

}

//---------------------------------------------------------------------------

 

/* Con este botón llamamos al metodo Disconnect(),

para desconectarnos del servidor */

 

void __fastcall TForm1::Button2Click(TObject *Sender)

{

NMFTP1->Disconnect();

}

//---------------------------------------------------------------------------

/* Llamada al metodo NList() , para obtener un listado

unicamente de nombres de ficheros y directorios */

 

void __fastcall TForm1::Button3Click(TObject *Sender)

{

NMFTP1->Nlist();

}

//---------------------------------------------------------------------------

/* Llamada al metodo List() , para obtener un listado

detallado de nombres de ficheros y directorios */

 

void __fastcall TForm1::Button4Click(TObject *Sender)

{

NMFTP1->List();

}

//---------------------------------------------------------------------------

/* Llamada al metodo ChangeDir() , para cambiar de directorio */

 

void __fastcall TForm1::Button5Click(TObject *Sender)

{

NMFTP1->ChangeDir(DirTxt->Text);

// Con esta sentencia , volvemos a realizar un Nlist()

Button3Click(this);

}

//---------------------------------------------------------------------------

 

 

 

 

/* Llamada al metodo Download(,) , para bajarnos un fichero

remoto y guardarlo en uno local */

 

void __fastcall TForm1::Button6Click(TObject *Sender)

{

NMFTP1->Download(RemoteTxt->Text, LocalTxt->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo Abort() , para abortar la operacion en curso */

void __fastcall TForm1::Button7Click(TObject *Sender)

{

NMFTP1->Abort();

}

//---------------------------------------------------------------------------

/* Llamada al metodo DownloadRestore(,) , para reiniciar una operación

de bajar un fichero desde el servidor.*/

void __fastcall TForm1::Button8Click(TObject *Sender)

{

NMFTP1->DownloadRestore(RemoteTxt->Text, LocalTxt->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo Rename(,) , para renombrar un fichero remoto. */

void __fastcall TForm1::Button18Click(TObject *Sender)

{

NMFTP1->Rename(Edit8->Text, Edit9->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo Reinitialize() , para reiniciar el proceso al

punto de autentificacion de usuario en el servidor. */

void __fastcall TForm1::Button17Click(TObject *Sender)

{

NMFTP1->Reinitialize();

PageControl1->ActivePage = TabSheet2;

}

//---------------------------------------------------------------------------

 

 

 

 

 

/* Llamada al metodo Delete() , para eliminar un fichero remoto. */

void __fastcall TForm1::Button16Click(TObject *Sender)

{

NMFTP1->Delete(Edit5->Text);

}

 

//---------------------------------------------------------------------------

 

/* Llamada al metodo MakeDirectory() , para crear un nuevo directorio

en el servidor remoto.*/

 

void __fastcall TForm1::Button14Click(TObject *Sender)

{

NMFTP1->MakeDirectory(Edit1->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo RemoveDir() , para eliminar un directorio vacio

en el servidor remoto. */

void __fastcall TForm1::Button15Click(TObject *Sender)

{

NMFTP1->RemoveDir(Edit2->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo UploadAppend(,) , para actualizar un fichero

remoto en el servidor. */

void __fastcall TForm1::Button11Click(TObject *Sender)

{

NMFTP1->UploadAppend(Edit3->Text, Edit4->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo UploadUnique() , para sobreescribir

un fichero remoto en el servidor . */

void __fastcall TForm1::Button12Click(TObject *Sender)

{

NMFTP1->UploadUnique(Edit3->Text);

}

//---------------------------------------------------------------------------

 

/* Llamada al metodo UploadRestore(,,) , para reiniciar la

subida al servidor de un fichero a partir de una determinada

posición. */

void __fastcall TForm1::Button13Click(TObject *Sender)

{

NMFTP1->UploadRestore(Edit3->Text, Edit4->Text, StrToInt(PosTxt->Text));

}

//---------------------------------------------------------------------------

/* Llamada al metodo Upload(,) , para subir al servidor un fichero local

especificando el nombre del fichero remoto del servidor. */

void __fastcall TForm1::Button10Click(TObject *Sender)

{

NMFTP1->Upload(Edit3->Text, Edit4->Text);

}

//---------------------------------------------------------------------------

/* Llamada al metodo Abort() , para abortar la operacion en curso */

void __fastcall TForm1::Button9Click(TObject *Sender)

{

NMFTP1->Abort();

}

//---------------------------------------------------------------------------

/* Cuando se genera el evento OnConnect, actualizamos

la barra de estado y mostramos el suceso en la ventana

de eventos. */

void __fastcall TForm1::NMFTP1Connect(TObject *Sender)

{

StatusBar1->SimpleText = "Conectado";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

/* Tras el evento OnConnectionFailed mostramos en la ventana

de traza de eventos el suceso */

 

void __fastcall TForm1::NMFTP1ConnectionFailed(TObject *Sender)

{

ShowMessage("Fallo en la conexión");

Memo2->Lines->Add("Fallo en la conexión");

}

//---------------------------------------------------------------------------

// Procedimiento a lanzar tras el evento OnDisconnect

void __fastcall TForm1::NMFTP1Disconnect(TObject *Sender)

{

if (StatusBar1 != 0)

StatusBar1->SimpleText = "Desconectado";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

/* En el caso de que se obtenga un error en el proceso se activará

el evento onError, que nos informará con un código de error y un mensaje */

 

void __fastcall TForm1::NMFTP1Error(TComponent *Sender, WORD Errno, AnsiString Errmsg)

{

ShowMessage("Error "+IntToStr(Errno)+": "+Errmsg);

}

//---------------------------------------------------------------------------

/* En el caso de que se obtenga un error en la ejecucion de algun

metodo se activara el evento OnFailure, en el siguiente procedimiento

capturamos el tipo de comando que ha producido el error e informamos al

usuario. */

void __fastcall TForm1::NMFTP1Failure(bool &handled, TCmdType Trans_Type)

{

switch (Trans_Type) {

case cmdChangeDir:

StatusBar1->SimpleText = "Error en el cambio de directorio";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdMakeDir:

StatusBar1->SimpleText = "Error al crear directorio";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDelete:

StatusBar1->SimpleText = "Error al borrar fichero";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdRemoveDir:

StatusBar1->SimpleText = "Error al borrar directorio";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdList:

StatusBar1->SimpleText = "Error al listar";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdRename:

StatusBar1->SimpleText = "Error al renombrar fichero";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdUpRestore:

StatusBar1->SimpleText = "Error al restaurar el fichero a enviar";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDownRestore:

StatusBar1->SimpleText = "Error al restaurar el fichero a bajar";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDownload:

StatusBar1->SimpleText = "Error en el envio desde el servidor";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdUpload:

StatusBar1->SimpleText = "Error en el envio a el servidor";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdAppend:

StatusBar1->SimpleText = "Error en el proceso de actualización en el servidor";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdReInit:

StatusBar1->SimpleText = "Fallo en la reinicialización de la sesión";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdAllocate:

StatusBar1->SimpleText = "Error en el proceso de reserva de memoria (Allocate)";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdNList:

StatusBar1->SimpleText = "Error en el comando Nlist";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDoCommand:

StatusBar1->SimpleText = "Fallo en la orden DoCommand";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

default: ShowMessage("Error en un comando desconocido."); break;

}

}

//---------------------------------------------------------------------------

/* Rutina que informa que se ha encontrado el host al que nos queremos

conectar , ya que se ha producido el evento OnHostResolved. */

void __fastcall TForm1::NMFTP1HostResolved(TComponent *Sender)

{

StatusBar1->SimpleText = "Host Resuelto";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

/* Rutina que informa que no se ha encontrado el host al que nos queremos

conectar , se ha producido el evento OnInvalidHost. Y volvemos a pedir

al usuario que introduzca un nuevo nombre de host. */

 

void __fastcall TForm1::NMFTP1InvalidHost(bool &handled)

{

AnsiString NewHost;

if (InputQuery("Host Inválido", "Por favor escoja otro host", NewHost))

{

NMFTP1->Host = NewHost;

handled = true;

}

}

//---------------------------------------------------------------------------

/* Esta rutina se encarga de listar el contenido del directorio remoto

utilizando un control TListView. */

void __fastcall TForm1::NMFTP1ListItem(AnsiString Listing)

{

TListItem * pItem;

pItem = ListView1->Items->Add();

pItem->Caption = Listing;

pItem->ImageIndex = ((Listing[1]!='d'))?0:1;

pItem->SubItems->Add(Listing);

 

}

//-----------------------------------------------------------------------------

 

 

 

 

 

 

 

 

/* Cada vez que se recibe un paquete de datos se genera el evento

OnPacketRecvd , de lo cual se informa en la aplicación con la rutina

siguiente . */

void __fastcall TForm1::NMFTP1PacketRecvd(TObject *Sender)

{

StatusBar1->SimpleText = IntToStr(NMFTP1->BytesRecvd)+" bytes de "+IntToStr(NMFTP1->BytesTotal)+" recibidos";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

/* Cada vez que se envia un paquete de datos se genera el evento

OnPacketSent , de lo cual se informa en la aplicación con la rutina

siguiente . */

void __fastcall TForm1::NMFTP1PacketSent(TObject *Sender)

{

StatusBar1->SimpleText = IntToStr(NMFTP1->BytesSent)+" bytes de "+IntToStr(NMFTP1->BytesTotal)+" enviados";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::NMFTP1Status(TComponent *Sender, AnsiString Status)

{

if (StatusBar1 != 0)

StatusBar1->SimpleText = Status;

}

//---------------------------------------------------------------------------

/* El evento OnSuccess se da cuando se ha ejecutado un metodo y la

ejecución del mismo ha finalizado correctamente , con la rutina siguiente

se captura el metodo en cuestion y se informa en la aplicacion. */

void __fastcall TForm1::NMFTP1Success(TCmdType Trans_Type)

{

switch(Trans_Type)

{

case cmdChangeDir:

StatusBar1->SimpleText = "Cambio de directorio con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdMakeDir:

StatusBar1->SimpleText = "Directorio creado con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDelete:

StatusBar1->SimpleText = "Eliminación de fichero con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdRemoveDir:

StatusBar1->SimpleText = "Borrado de directorio con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdList:

StatusBar1->SimpleText = "Listado con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdRename:

StatusBar1->SimpleText = "Operación renombrar con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdUpRestore:

StatusBar1->SimpleText = "Exito al restaurar el proceso de envio";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDownRestore:

StatusBar1->SimpleText = "Exito al restaurar el proceso de copia";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDownload:

StatusBar1->SimpleText = "Copia al cliente con éxito (Download)";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdUpload:

StatusBar1->SimpleText = "Envio al servidor con éxito (Upload)";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdAppend:

StatusBar1->SimpleText = "Exito en el envio de actualización al servidor";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdReInit:

StatusBar1->SimpleText = "Reinicio de sesión con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdAllocate:

StatusBar1->SimpleText = "Reserva de memoria realizada (Allocate)";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdNList:

StatusBar1->SimpleText = "Comando NList con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

case cmdDoCommand:

StatusBar1->SimpleText = "Orden DoCommand con éxito";

Memo2->Lines->Add(StatusBar1->SimpleText);

break;

}

}

//---------------------------------------------------------------------------

/* Cuando se inicia una conexion de datos para una transferencia se

genera el evento OnTransactionStart , con lo que podemos informar al

usuario del inicio de la misma. */

void __fastcall TForm1::NMFTP1TransactionStart(TObject *Sender)

{

StatusBar1->SimpleText = "Iniciando la transferencia de datos";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

/* Cuando finaliza o se cierra la conexion de datos para una transferencia

se genera el evento OnTransactionStop ,y pasamos a informar del fin de la

misma. */

void __fastcall TForm1::NMFTP1TransactionStop(TObject *Sender)

{

StatusBar1->SimpleText = "Transferencia Completada";

Memo2->Lines->Add(StatusBar1->SimpleText);

}

//---------------------------------------------------------------------------

/* El evento OnUnSupportedFunction se genera cuando el servidor al cual

estamos conectados no soporta o no reconoce cierta orden o comando,

aqui lo que hacemos es capturar dicha orden y lanzar un mensaje adicional.*/

void __fastcall TForm1::NMFTP1UnSupportedFunction(TCmdType Trans_Type)

{

switch(Trans_Type)

{

case cmdChangeDir:

ShowMessage("Comando ChangeDir no soportado ");

break;

case cmdMakeDir:

ShowMessage("Comando MakeDir no soportado");

break;

case cmdDelete:

ShowMessage("Comando Delete no soportado");

break;

case cmdRemoveDir:

ShowMessage("Comando RemoveDir no soportado");

break;

case cmdList:

ShowMessage("Coamndo List no soportado");

break;

case cmdRename:

ShowMessage("Comando Rename no soportado");

break;

case cmdUpRestore:

ShowMessage("Comando UploadRestore no soportado");

break;

case cmdDownRestore:

ShowMessage("DownloadRestore no soportado");

break;

case cmdDownload:

ShowMessage("Comando Download no soportado");

break;

case cmdUpload:

ShowMessage("Comando Upload no soportado");

break;

case cmdAppend:

ShowMessage("Comando UploadAppend no soportado");

break;

case cmdReInit:

ShowMessage("Cmando ReInit no soportado");

break;

case cmdAllocate:

ShowMessage("Comando Allocate no soportado");

break;

case cmdNList:

ShowMessage("Comando NList no soportado");

break;

case cmdDoCommand:

ShowMessage("Orden DoCommand no soportada");

break;

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::RadioGroup1Click(TObject *Sender)

{

ListView1->ViewStyle=(TViewStyle) RadioGroup1->ItemIndex;

}

//---------------------------------------------------------------------------