Delphi: Пишем шаблон клиент-серверного приложения.
Продолжая тему разработки собственной утилиты администрирования, в данной статье я рассмотрю типовой шаблон программы клиент-сервер, на базе которой можно разрабатывать собственные клиент-серверные приложения. Данный типовой шаблон для простоты понимания и удобства применения будет рассмотрен на примере компонентов ClientSocket и ServerSocket.
Примечание
Надеюсь все объяснил доступно =). А теперь приступим к делу и начнем мы с серверной части. Для этого создадим проект и скинем на форму компонент ServerSocket. В настройках компонента ServerSocket укажем следующее:
Name = ss
Port = 4321
ServerType = stNonBlocking
А также для удобства скинем компонент Memo, в который будем выводить всякую инфу. Дадим имя компоненту log.
Далее, для компонента ServerSocket определяем метод onClientConnect, чтобы определять момент подключения клиентов. Вставим следующий код:
procedure TForm1.ssClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
myDate : TDateTime;
formattedDateTime : string;
begin
mydate:=Now;
DateTimeToString(formattedDateTime, 'c', myDate);
log.Lines.Add(formattedDateTime+': Есть коннект c '+Socket.RemoteAddress);
{ далее вы можете вставить свой код }
end;
А теперь определим метод onClientRead, в котором будем обрабатывать получаемые сообщения от клиентов:
procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket); var s:string; begin s:=Socket.ReceiveText; log.Lines.Add(s); end;
Определим метод onClientDisconnect, чтобы фиксировать факт отключения клиента:
procedure TForm1.ssClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); var myDate : TDateTime; formattedDateTime : string; begin mydate:=Now; DateTimeToString(formattedDateTime, 'c', myDate); log.Lines.Add(formattedDateTime+': Клиент '+socket.RemoteAddress+' отключился.'); end;
На этом с серверной частью покончено =).
Приступим к клиентской части. Для этого создадим новый проект, скинем на форму компонент ClientSocket и таймер. В настройках компонента укажем следующее:
Name = сs
Port = 4321
ClientType = ctNonBlocking
Address = 127.0.0.1
Для простоты пояснения я в Address указал «петлю». Но для гибкости приложения рекомендую это поле обрабатывать программно, во время CreateForm при обработке конфигурационного файла, в котором можно указывать нужный IP-адрес сервера.
Здесь также для удобства скинем на форму компонент Memo, в который будем выводить техническую инфу. Имя дадим соответствующее log.
Для компонента ClientSocket определяем метод onError для того, чтобы обрабатывать исключения, возникшие в момент подключения клиента к серверу. Вставим следующий код:
procedure TForm1.csError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
var
myDate : TDateTime;
formattedDateTime : string;
begin
if ErrorEvent= eeConnect then
begin
cs.Active:=false;
{добавить запись в журнал};
mydate:=Now;
DateTimeToString(formattedDateTime, 'c', myDate);
log.lines.Add(formattedDateTime+': Невозможно установить соединение с сервером - '+cs.Address);
end;
ErrorCode:=0;
{ далее вы можете вставить свой код }
end;
Теперь определим метод onConnect. Вставим следующий код:
procedure TForm1.csConnect(Sender: TObject; Socket: TCustomWinSocket); var myDate : TDateTime; formattedDateTime : string; begin mydate:=Now; DateTimeToString(formattedDateTime, 'c', myDate); log.lines.Add(formattedDateTime+': Соединение с сервером - '+socket.RemoteAddress+' установлено.'); end;
И чтобы фиксировать момент потери связи с сервером, определим метод onDisconnect:
procedure TForm1.csDisconnect(Sender: TObject; Socket: TCustomWinSocket); var myDate : TDateTime; formattedDateTime : string; begin mydate:=Now; //получим текущее время DateTimeToString(formattedDateTime, 'c', myDate); //преобразуем в строку log.Lines.Add(formattedDateTime+': Соединение с сервером '+socket.RemoteAddress+' потеряно.'); end;
Таймер настроим так:
Name = te
Interval = 5000
И определяем метод onTimer. Вставим следующий код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if not cs.Active then
begin
cs.Active:=true;
end;
cs.Socket.SendText('ping client');
end;
Данный код проверяет наличие соединения с сервером и в случае его отсутствия пытается его установить.
И каждые 5 секунд отправляет серверу сообщение «ping client».
Вот примерно так выглядит типовой шаблон приложения «клиент-сервер».
Примечание
Рабочий пример можно скачать отсюда.
Если есть кому что добавить или задать вопрос по теме — прошу отписываться в комментах ;)


(11 голосов, средний: 4,64 из 5)
Пример про то, как избавиться от ошибки «Asynchronous socket error 10061″ не рабочий… обновите ссылку, пожалуйста…
пример рабочий, ток в исходнике каким то нелепым образом обработчик ошибки закоментирован, просто раскоментируйте и заново скомпилируйте пример и все будет окей ;)
Есть необходимость небольшую базу данных, созданную в Access, переписать на Delphi с использованием «клиент-сервер».
Может, чем-нибудь подсобишь?
@Andrew
Coffein пока вне зоны досягаемости, будет после 27го. Тыкну чтобы отписался как будет возможность, но на сколько известно мне, с Access он не работал.
P.S. Сам delphi не знаю, ничем помочь не могу :).
@Andrew
Это зависит от техзадания, вообщем пиши в аську, обсудим, может чем и подсоблю
а как быть с динамическими IP ?
Сохраняй в конфиг или ini-файле. И программно обрабатывай
а у меня почему-то клиент сервер не находит…
сервак скинул на виртуальную машину, ip настроил, порты 4321 как в примере. при попытке подключения вызывается обработчик onerror
уже не надо, разобрался))) оказалось у сервера свойсво active было установлено в false))))
у меня вопрос такой: имеются две БД на delphi 7…надо организовать связь между ними…т.е. БД_1 в определенные моменты (по необходимости) будет посылать запросы на БД_2 с целью получения некоторых данных….БД_2 по запросу передает некоторые данные на БД_1, которые заносятся в таблицы БД_1….можно ли организовать все это выше описанным методом и если да может какой совет для начала додите, пожалуйста)))
ребят! подскажите!
как можно сделать так, что бы клиент находил ин-ю о пк и отправлял её обратно на сервер в виде текстового файла?
помогите плз