Постановка задачи
Разработать FTP-клиент. Программа должна соединяться с FTP-cepвером, проходить аутентификацию и предоставлять пользователю возможность работать с файлами, которые находятся на сервере. У пользователя должна быть возможность передавать и получать файлы, создавать и удалять каталоги и т.п. Также пользователь может выполнять свои собственные команды на сервере.
Разработка формы
Создайте новый проект Delphi. Приготовьтесь к тому, что форма получится довольно большой (ширина — около 800 пикселей) и будет содержать большое количество разных кнопок и полей ввода. Присвойте ей заголовок FTP-client (свойство Caption) и разместите компоненты согласно табл. 18.1.
Таблица 18.1. Свойства формы FTP-клиента
Компонент | Свойство | Значение | Пояснение |
Label1 (категория Standard ) | Caption | FTP-сервер | Надпись метки |
Left | 56 | Отступ слева | |
Top | 16 | Отступ сверху | |
Label2 | Caption | РРјСЏ пользователя | Надпись метки |
Left | 16 | Отступ слева | |
Top | 48 | Отступ сверху | |
Label3 | Caption | Пароль | Надпись метки |
Left | 72 | Отступ слева | |
Top | 80 | Отступ сверху | |
Edit1 (категория Standard ) | Name | ftpserver | Новое имя компонента |
Text | ftp.narod.ru | Адрес FTP-сервера | |
Left | 120 | Отступ слева | |
Top | 8 | Отступ сверху | |
Edit2 | Name | name | Новое имя компонента |
Text | test6001 | РРјСЏ пользователя | |
Left | 120 | Отступ слева | |
Top | 40 | Отступ сверху | |
Edit3 | Name | pass | Новое имя компонента |
Left | 120 | Отступ слева | |
Top | 72 | Отступ сверху | |
Edit4 | Name | port | Новое имя компонента |
Text | 21 | РРјСЏ пользователя | |
Left | 120 | Отступ слева | |
Top | 104 | Отступ сверху | |
Edit5 | Name | del | Новое имя компонента |
Left | 512 | Отступ слева | |
Top | 8 | Отступ сверху | |
Edit6 | Name | cd | Новое имя компонента |
Left | 512 | Отступ слева | |
Top | 40 | Отступ сверху | |
Edit7 | Name | cmd | Новое имя компонента |
Left | 512 | Отступ слева | |
Top | 72 | Отступ сверху | |
Edit8 | Name | md | Новое имя компонента |
Left | 512 | Отступ слева | |
Top | 104 | Отступ сверху | |
Edit9 | Name | rd | Новое имя компонента |
Left | 512 | Отступ слева | |
Top | 136 | Отступ сверху | |
Edit10 | Name | download | Новое имя компонента |
Left | 512 | Отступ слева | |
Top | 168 | Отступ сверху | |
Button1 (категория Standard ) | Caption | Подключиться | Надпись на кнопке |
Left | 8 | Отступ слева | |
Top | 144 | Отступ сверху | |
Button2 | Caption | Отключиться | Надпись на кнопке |
Left | 123 | Отступ слева | |
Top | 144 | Отступ сверху | |
Button3 | Caption | Загрузить файл на сервер | Надпись на кнопке |
Left | 512 | Отступ слева | |
Top | 200 | Отступ сверху | |
Button4 | Caption | Удалить | Надпись на кнопке |
Left | 672 | Отступ слева | |
Top | 8 | Отступ сверху | |
Button5 | Caption | Рзменить каталог | Надпись РЅР° РєРЅРѕРїРєРµ |
Left | 672 | Отступ слева | |
Top | 40 | Отступ сверху | |
Button6 | Caption | Выполнить команду | Надпись на кнопке |
Left | 672 | Отступ слева | |
Top | 72 | Отступ сверху | |
Button7 | Caption | Создать каталог | Надпись на кнопке |
Left | 672 | Отступ слева | |
Top | 104 | Отступ сверху | |
Button8 | Caption | Удалить каталог | Надпись на кнопке |
Left | 672 | Отступ слева | |
Top | 136 | Отступ сверху | |
Button9 | Caption | Скачать файл | Надпись на кнопке |
Left | 672 | Отступ слева | |
Top | 168 | Отступ сверху | |
Memo (категория Standard ) | Name | status1 | Новое имя компонента, предназначенного для отображения состояния соединения |
Lines | Статус: | Текст в поле | |
Left | 264 | Отступ слева | |
Top | 8 | Отступ сверху | |
Height | 217 | Высота | |
Width | 233 | РЁРёСЂРёРЅР° | |
OpenDialog (категория Dialogs ) | Name | Open1 | Новое имя компонента, который будет использоваться для открытия файлов |
SaveDialog (категория Dialogs ) | Name | Save1 | Новое имя компонента, который будет использоваться для сохранения файлов |
NMFTP (категория FastNet ) | Name | ftp | Новое имя главного компонента программы |
Полученная форма должна соответствовать рис. 18.1.
Рис. 18.1. Форма FTP-клиента
Разработка программного кода
Обработаем нажатия кнопок соединения и отключения от сервера. Обработчик события OnClick для кнопки Подключиться:
procedure TForm1.Button1Click(sender: TObject);
begin
 ftp.Host:= ftpserver.Text; //ftp-сервер
 ftp.UserID:= name.Text; //логин
 ftp.Password:= pass.Text; // пароль
 ftp.Port:= StrToInt(port.Text) ; //порт для подключения
 //соединяемся с сервером
В if not ftp . Connected then ftp.Connect;
end;
Здесь мы считываем все данные, которые необходимы для соединения с сервером. После этого мы пытаемся соединиться с сервером. Об успешности этой операции можно будет узнать в поле состояния.
Обработаем нажатие кнопки Отключиться:
procedure TForm1.Button2Click(Sender: TObject);
begin
 if ftp . Connected then //если соединен
 ftp.Disconnect; //отключиться от сервера
end;
Если при нажатии кнопки Отключиться установлено соединение с сервером, то мы разрываем его.
Теперь обработаем нажатие кнопок, которые служат для работы с сервером. Обработчик события OnClick для кнопки Удалить:
procedure TForm1.Button4Click(Sender : TObject);
begin
 ftp.Delete(del.text); //удалить файл
end;
Здесь мы удаляем файл, имя которого пользователь ввел в поле рядом с кнопкой.
Обработаем нажатие РєРЅРѕРїРєРё Рзменить каталог:
procedure TForm1.Button5Click(Sender: TObject);
begin
 ftp.ChangeDir(cd.Text); //изменяем каталог
end;
Устанавливаем текущим тот каталог, который указан в поле cd.
Обработаем нажатие кнопки Выполнить команду:
procedure TForm1.Button6Click(Sender: TObject);
begin
 ftp.DoCommand(cmd.Text); //выполнение команды
end;
При работе с сервером мы предоставляем пользователю возможность работать не только с помощью команд, предусмотренных в интерфейсе, но и выполнять на сервере любые произвольные команды. Для этого у нас есть поле cmd, в котором пользователь вводит команду, и кнопка Выполнить команду, по нажатию которой введенная команда выполняется.
Обработаем нажатие кнопки Создать каталог:
procedure TForm1.Button7Click(Sender: TObject);
begin
 ftp.MakeDirectory(md.Text); //создать каталог
end;
Обработаем нажатие кнопки Удалить каталог:
procedure TForm1.Button8Click(Sender: TObject);
begin
 ftp.RemoveDir(rd.Text); //удалить каталог
end;
Обработаем нажатие кнопки Скачать файл:
procedure TForm1.Button9Click(Sender: TObject);
begin
 //открытие диалогового окна сохранения файла
В if Save1.Execute
 then //скачиваем указанный файл
В ftp.Download(download.Text, save1.FileName)
 else ShowMessage('File not saved!' ); {если пользователь отказался сохранять файл}
end;
Сначала мы предлагаем пользователю указать имя и путь размещения полученного файла. Затем мы загружаем файл и размещаем его по указанному пути.
Наконец, обработаем нажатие кнопки Загрузить файл на сервер:
procedure TForm1.Button3Click(Sender: TObject);
var
В i: integer;
 FName, temp: string; //для получения имени файла
begin
 if not Open1.Execute then ShowMessage('Файл не выбран!')
В else begin
 //очищаем переменные, которые содержат имя файла
В temp:= '';
В FName:= '';
 //получаем имя файла
В for i: = Length(Open1.FileName) downto 1 do
В begin
В if Open1.FileName[i] = '\' then break;
В temp:= temp+ Open1.FileName[i];
В end;
В for i:=length(temp) downto 1 do
В fname:= fname + temp[i];
 ftp.Upload(Open1.FileName, FName) ; //загружаем файл
В end;
end;
Здесь мы сначала просим пользователя выбрать файл, который он хочет передать на сервер. Затем узнаем имя выбранного файла и загружаем его на сервер с таким же именем.
В общем, наш ftp-клиент уже полностью работоспособен и выполняет все необходимые функции. Единственное, что осталось сделать, — реализовать извещение пользователя о протекании всех операций и обо всех ошибках. Для этого следует создать несколько обработчиков событий компонента ftp.
Событие в случае возникновения ошибки при проверке имени и пароля — OnAuthеntiсatiоnFailed:
procedure TForm1.ftpAuthenticationFailed(var Handled: Boolean);
begin
 status1.Lines.Add('Неверное имя или пароль');
end;
Событие при подключении — OnConnect:
procedure TForm1.ftpConnect(Sender:tobject);
begin
 status1.Lines.Add('Подключено ');
 //локальный ip-адрес
 status1Lines.Add('IP клиента: ' + ftp.LocalIP) ;
 //удаленный ip-адрес
 status1Lines.Add('IPсервера: ' + ftp.RemoteIP);
end;
Событие в случае возникновения ошибки при подключении — OnConnectionFailed:
procedure TForm1.ftpConnectionFailed(Sender: TObject);
begin
 status1.Lines.Add('He удалось подключиться к серверу');
end;
Событие при отключении от сервера — OnDisconnect:
procedure TForm1.ftpDisconnect(Sender: TObject);
begin
 status1.Lines.Add('Отключено');
end;
Событие в случае возникновения некоторой ошибки — OnError:
procedure TForml.ftpError(Sender: TComponent; Errno: Word; Errmsg: String);
begin
 status1.Lines.Add('Ошибка: ' + errmsg);
end;
Событие в случае возникновения ошибки при подключении к серверу — OnInvaIidHost:
procedure TForm1.ftpInvalidHost(var Handled: Boolean);
begin
 status1.Lines.Add('Ошибка при подключении к серверу');
end;
Событие при изменении состояния — OnStatus:
procedure TForm1.ftpStatus(Sender: TComponent; Status: String);
begin
В status1.Lines.Add(Status);
end;
Событие при успешном выполнении операции — OnSuccess:
procedure TForm1.ftpSuccess(Trans_Type: TCmdType);
begin
 status1.Lines.Add('Успешно');
end;
Событие начала передачи данных — OnTransactionStart:
procedure TForm1.ftpTransactionStart(Sender: TObject);
begin
 status1.Lines.Add('Начало передачи данных');
end;
Событие завершения передачи данных — OnTransactionStop :
procedure TForm1.ftpTransactionStop(Sender: TObject);
begin
 statusl.Lines.Add('Конец передачи данных');
end;
Теперь программа полностью готова к использованию. Если у вас нет собственного Web-сайта, то для тестирования FTP-клиента можете зарегистрировать сайт на бесплатном хостинге.
Полный исходный код модуля
Полный код программного модуля FTP-клиента представлен в листинге 18.1.
Листинг 18.1. Программный модуль FTP-клиента
unit Unit1;
interface
uses
В Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, NMFtp, StdCtrls, Psock;
type
В TForm1 = class(TForm)
В ftp: TNMFTP;
В ftpserver: TEdit;
В Label1: TLabel;
В Label2: TLabel;
В name: TEdit;
В Label3: TLabel;
В pass: TEdit;
В Label4: TLabel;
В port: TEdit;
В Button1: TButton;
В Button2: TButton;
В status1: TMemo;
В Button3: TButton;
В Open1: TOpenDialog;
В Button4: TButton;
В del: TEdit;
В Button5: TButton;
В cd: TEdit;
В cmd: TEdit;
В Button6: TButton;
В md: TEdit;
В Button7: TButton;
В rd: TEdit;
В Button8: TButton;
В download: TEdit;
В Button9: TButton;
В Save1: TSaveDialog;
В procedure Button1Click(Sender: TObject);
В procedure ftpStatus(Sender: TComponent; Status: String);
В procedure ftpError(Sender: TComponent; Errno: Word; Errmsg : String);
В procedure ftpDisconnect(Sender: TObject);
В procedure ftpConnect(Sender: TObject);
В procedure ftpConnectionFailed(Sender: TObject);
В procedure ftpInvalidHost(var Handled: Boolean);
В procedure ftpSuccess(Trans_Type: TCmdType);
В procedure ftpTransactionStart(Sender: TObject);
В procedure ftpTransactionStop(Sender: TObject);
В procedure ftpAuthenticationFailed(var Handled: Boolean);
В procedure Button2Click(Sender: TObject);
В procedure Button3Click(Sender: TObject);
В procedure FormDestroy(Sender: TObject);
В procedure Button5Click(Sender: TObject);
В procedure Button4Click(Sender: TObject);
В procedure Button6Click(Sender: TObject);
В procedure Button7Click(Sender: TObject);
В procedure Button8Click(Sender: TObject);
В procedure Button9Click(Sender: TObject);
private
В { Private declarations }
public
В { Public declarations }
end;
var
В Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(sender: TObject);
begin
 ftp.Host:= ftpserver.Text; //ftp-сервер
 ftp.UserID:= name.Text;//логин
 ftp.Password:= pass.Text;// пароль
 ftp.Port:= StrToInt(port.Text); //порт для подключения
 //соединяемся с сервером
В if not ftp.Connected then ftp.Connect;
end;
procedure TForm1.ftpStatus(Sender: TComponent; Status: String);
begin
В status1.Lines.Add(Status);
end;
procedure TForml.ftpError(Sender: TComponent; Errno: Word; Errmsg: String);
begin
 status1.Lines.Add('Ошибка: ' + errmsg);
end;
procedure TForm1.ftpDisconnect(Sender: TObject);
begin
 status1.Lines.Add('Отключено');
end;
procedure TForm1.ftpConnect(Sender:tobject);
begin
 status1.Lines.Add('Подключено');
 //локальный ip-адрес
 status1Lines.Add('IP клиента: ' + ftp.LocalIP);
 //удаленный ip-адрес
 status1Lines.Add('IPсервера: ' + ftp.RemoteIP);
end;
procedure TForm1.ftpConnectionFailed(Sender: TObject);
begin
 status1.Lines.Add('He удалось подключиться к серверу');
end;
procedure TForm1.ftpInvalidHost(var Handled: Boolean);
begin
 status1.Lines.Add('Ошибка при подключении к серверу');
end;
procedure TForm1.ftpSuccess(Trans_Type: TCmdType);
begin
 status1.Lines.Add('Успешно');
end;
procedure TForm1.ftpTransactionStart(Sender: TObject);
begin
 status1.Lines.Add('Начало передачи данных');
end;
procedure TForm1.ftpTransactionStop(Sender: TObject);
begin
 statusl.Lines.Add('Конец передачи данных');
end;
procedure TForm1.ftpAuthenticationFailed(var Handled: Boolean);
begin
 status1.Lines.Add('Неверное имя или пароль');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
 if ftp.Connected then//если соединен
 ftp.Disconnect;//отключиться от сервера
end;
procedure TForm1.Button3Click(Sender: TObject);
var
В i: integer;
 FName, temp: string; //для получения имени файла
begin
 if not Open1.Execute then ShowMessage('Файл не выбран!')
В else begin
 //очищаем переменные, которые содержат имя файла
В temp:= '';
В FName:= '';
 //получаем имя файла
В for i: = Length(Open1.FileName) downto 1 do
В begin
В if Open1.FileName[i] = '\' then break;
В temp:= temp+ Open1.FileName[i];
В end;
В for i:=length(temp) downto 1 do
В fname:= fname + temp[i];
 ftp.Upload(Open1.FileName, FName); //загружаем файл
В end;
end;
procedure TForm1.FormDestroy(Sender: TObject) ;
begin
В if ftp.Connected then ftp.Disconnect;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
 ftp.ChangeDir(cd.Text); //изменяем каталог
end;
procedure TForm1.Button4Click(Sender : TObject);
begin
 ftp.Delete(del.text); //удалить файл
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
 ftp.DoCommand(cmd.Text); //выполнение команды
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
 ftp.MakeDirectory(md.Text); //создать каталог
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
 ftp.RemoveDir(rd.Text); //удалить каталог
end;
procedure TForm1.Button9Click(Sender: TObject);
begin
 //открытие диалогового окна сохранения файла
В if Save1.Execute
 then //скачиваем указанный файл
В ftp.Download(download.Text, save1.FileName)
 else ShowMessage('File not saved!'); {если пользователь отказался сохранять файл}
end;
end.
⊚ Р’СЃРµ файлы проекта Рё исполняемый файл рассмотренной программы находятся РЅР° прилагаемом Рє РєРЅРёРіРµ компакт-РґРёСЃРєРµ РІ папке Chapter_18.