Мегаобучалка Главная | О нас | Обратная связь


Опция заполнения класса



2020-02-03 154 Обсуждений (0)
Опция заполнения класса 0.00 из 5.00 0 оценок




Эта функция автоматически генерирует исходный код для любых составных частей нового класса (свойств и методов), которые уже объявлены в секции interface, а также создает объявление для тех элементов, которые уже описаны в секции implementation.

Чтобы создать описание объявленных свойств и методов, необходимо установить курсор в любое место объявления класса в секции interface и нажать комбинацию клавиш ++.

После этого Delphi, во-первых, создаст для объявленных свойств класса не- обходимые свойства и методы для чтения и записи в секции private. Во- вторых, в секции implementation будет сгенерировано описание необходимых методов.

Например, имеется простейший класс:

type
TSimpleObject = class (TObject)
property Empty: Integer;
function ClearEmpty: Boolean;
end;

Тогда, после нажатия комбинации клавиш ++, исходный код в секции interface будет приведен к следующему виду:

type
TSimpleObject = class (TObject)
property Empty: Integer read FEmpty write SetEmpty;
function ClearEmpty: Boolean;
private
FEmpty: Integer;
procedure SetEmpty(const Value: Integer);
end;

А в секции implementation появятся следующие строки:

function TSimpleObject.ClearEmpty: Boolean;
begin

end;

procedure TSimpleObject.SetEmpty(const Value: Integer);
begin
FEmpty := Value;
end;

Межпрограммное взаимодействие

Часто возникает необходимость организовать взаимодействие программ, написанных разными людьми или даже разными фирмами. Задача решается в рамках идеологии «клиент-сервер», когда одно приложение должно реагировать на запросы других приложений. Наконец, с развитием сетей совершенно обычной стала задача взаимодействия приложения на разных машинах.

Для организации взаимодействия между задачами существует очень много инструментов. Некоторые из них позволяют работать в рамках только одной машины, некоторые - в рамках локальной или глобальной сети. Связь между двумя программами можно установить таким образом, что изменения в одном приложении будут отражаться во втором. Например, если Вы меняете число в электронной таблице, то во втором приложении данные обновятся автоматически и отобразят изменения. Кроме того, можно из своего приложения управлять другими приложениями такими, как Word for Windows, Excel и др.

Dynamic Data Exchange (DDE)

DDE дает возможность перейти через рамки приложения и взаимодействовать с другими приложениями и системами Windows. Dynamic Data Exchange получило свое имя потому, что позволяет двум приложениям обмениваться данными (текстовыми, через глобальную память) динамически во время выполнения. DDE - давний и прижившийся протокол обмена данными, появившийся еще на заре эры Windows. Ниша, занимаемая DDE - это оперативная передача и синхронизация данных в приложениях.

Приложения, использующие DDE, подразделяются на две категории: клиенты и серверы. Оба участника процесса совершают контакты (conversations) по определенным темам (topics), при этом в рамках темы производится обмен элементами данных (items). Устанавливает контакт DDE-клиент, который посылает запрос, содержащий имена контакта и темы. После установления контакта всякое изменение элемента данных на DDE-сервере передается элементу данных клиента. Одно и то-же приложение может быть одновременно и сервером, и клиентом (например, MicroSoft Word).

DDE-серверы

Для построения DDE-сервера в Delphi имеются два объекта, расположенные на странице System Палитры Компонент - TDdeServerConv и TDdeServerItem. Обычно в проекте используется один объект TDdeServerConv и один или более TDdeServerItem. Для получения доступа к сервису DDE-сервера, клиенту потребуется знать несколько параметров: имя сервиса (Service Name) - это имя приложения (обычно - имя выполняемого файла без расширения EXE, возможно с полным путем); Topic Name - в название темы; Item Name – название элемента данных.

Назначение объекта TDdeServerConv - общее управление DDE и обработка запросов от клиентов на выполнение макроса. Последнее выполняется в обработчике события OnExecuteMacro, например, как это сделано ниже:

procedure TDdeSrvrForm.DoMacro(Sender: TObject;Msg: TStrings);
var
Text: string;
Begin
Text := '';
if Msg.Count > 0 then Text := Msg.Strings[0];
MessageDlg ('Executing Macro - ' + Text, mtInformation, [mbOK], 0);
End;

Важнейшим свойством компонента TDdeServerConv является название темы, содержащееся в свойстве Name. Клиент должен знать это имя при установлении контакта, за исключением случая, когда он подключается к данным контакта, скопированным в буфер обмена.

В моменты открытия и закрытия контакта возникают события:

Property OnOpen: tNotifyEvent;
Property OnClose: tNotifyEvent;

Объект TDdeServerItem связывается с TDdeServerConv посредством свойства

Property ServerConv:tDDEServerConv,

и определяет, что, собственно, будет пересылаться по DDE. В принципе, потокол DDE подразумевает обмен любыми данными, формат которых зарегистрирован в системе для передачи через буфер обмена. Однако для рассматриваемых компонентов эти возможности ограничиваются только текстовыми данными. Для этого у компонента TDdeServerItem есть свойства Text и Lines (Text имеет то же значение, что и Lines[0]).

Property Text:string;
Property Lines:tStrings;

При изменении значения этих свойств автоматически происходит пересылка обновленных данных во все приложения-клиенты, установившие связь с сервером.

Данный компонент позволяет также осуществлять установление связи через буфер обмена (Clipboard). Для этого служит метод CopyToClipboard. Необходимая информации помещается в через буфер обмена и может быть вызвана из приложения-клиента при установлении связи. Обычно, в DDE-серверах для этого есть специальный пункт меню Paste Special или Paste Link.

DDE-клиенты

Для построения DDE-клиента в Delphi используются два компонента TDDEClientConv и TDDEClientItem. Аналогично серверу, в программе обычно используется один объект TDDEClientConv и один и более связанных с ним TDDEClientItem.

TDDEClientConv служит для установления связи с сервером и общим управлением DDE-связью. Установить связь с DDE-сервером можно как во время разработки, так и во время выполнения программы, причем двумя способами. Первый способ - заполнить вручную необходимые свойства компонента. Это DdeService, DdeTopic и ServiceApplication. Если во время разработки дважды щелкнуть на одном из первых двух свойств в Инспекторе Объектов - появится диалог для определения DDE-связи. Для установления связи через Clipboard в диалоге есть специальная кнопка Past Link. Ей можно воспользоваться, если Вы запустили DDE-сервер, сохранили каким-то образом информацию о связи и вошли в этот диалог. Например, если DDE-сервером является DataBase Desktop, то нужно загрузить в него какую-нибудь таблицу Paradox, выбрать любое поле и выбрать пункт меню Edit|Copy. Свойство ServiceApplication заполняется в том случае, если в поле DDEService содержится имя, отличное от имени программы, либо если эта программа не находится в текущей директории. В этом поле указывается полный путь и имя программы без расширения (.EXE). Данная информация нужна для автоматического запуска сервера при установлении связи по DDE, если тот еще не был запущен.

Имена сервера DDE и темы содержатся в свойствах:

Property DDEService:string;
Property DDETopic:string;

Способ вхождения в контакт определяется свойством

Property ConnectMode:tDataMode;
Type tDataMode = (DDEAutomatic,DDEManual);

Метод

Function SetLinc(const Service: string; const Topic: string):Boolean;
Присваивает свойствам DDEService и DDETopic соответствующие значения, а в случае, если задан режим DDEAutomatic, и устанавливает контакт. В режиме DDEManual для установления контакта необходимо дополнительно вызвать метод

Function OpenLink: Boolean;
Этот метод сначала закрывает предыдущий контакт, затем пытается связаться с сервером DDEService на тему DDETopic. Если это не удается сразу, предпринимается попытка загрузить приложение с именем, определенным в свойстве:

Property ServiceApplication: string;
Можно связаться с сервером, поместившим данные в буфер обмена с помощью метода

Function PasteLink: boolean;

Ниже приведен пример процедуры, осуществляющей связь с сервером.

procedure TMainForm.doNewLink(Sender: TObject);
begin
DdeClient.SetLink(AppName.Text, TopicNameEdit.Text);
DdeClientItem.DdeConv := DdeClient;
DdeClientItem.DdeItem := ItemName.Text;
end;

procedure TMainForm.doPasteLink(Sender: TObject);
var
Service, Topic, Item : String;
begin
if GetPasteLinkInfo (Service, Topic, Item) then begin
AppName.Text := Service;
TopicName.Text := Topic;
ItemName.Text := Item;
DdeClient.SetLink (Service, Topic);
DdeClientItem.DdeConv := DdeClient;
DdeClientItem.DdeItem := ItemName.Text;
end;
end;

После того, как установлена связь, нужно позаботиться о поступающих по DDE данных, это делается в обработчике события OnChange объекта TDdeClietItem:

procedure TFormD.DdeClientItemChange(Sender: TObject);
begin
DdeDat.Lines := DdeClientItem.Lines;
end;

Это единственная задача объекта TDdeClientItem.

Свойство

Property DDEConv: TddeClientConv

Этого компонента предназначено для связи с соответствующим объектом DdeClientConv. А свойство

Property DDEItem:string;

Должно содержать имя элемента данных.

Свойства

Property Text: string;
Property Lines: tStrings;

Аналогичны соответствующим свойствам tDDEServerItem и содержат данные.

На объект TDdeClientConv возлагаются еще две задачи: пересылка данных на сервер и выполнение макросов. Для этого у данного объекта есть соответствующие методы.

Function ExecuteMacroLines(Cmd:tStrings, WaitFlg:Boolean):Boolean;
Function PokeDataLines(const Item:string,Data:tStrings):Boolean;

Обмен сообщениями

Как уже упоминалось ранее, операционная система Windows® основана на сообщениях, возникающих в результате действий пользователя, аппаратуры компьютера или других программ. Поведение каждого окна полностью определяется тем, какие оно принимает сообщения и как их обрабатывает. В большинстве случаев, обработка сообщений в Delphi выполняется через события. Однако, бывают ситуации, когда может потребоваться послать и/или обработать сообщение самостоятельно. Существуют два типа сообщений, которые могут потребовать обработки в обход обычной системы сообщений Delphi:

Сообщения Windows®, не обрабатываемые VCL
Сообщения, определяемые пользователем

В принципе, сообщения делятся на две категории:

Командные сообщения
Уведомляющие сообщения

Командные сообщения используются как программистами, тек и Windows®. Они управляют элементам операционной системы и прикладным программам. Уведомляющие сообщения содержат информацию об изменении состояния окон Windows®, их отдельных элементов и устройств системы. Они посылаются только самой средой окон Windows®.

Каждое сообщение имеет два параметра: WPARAM и LPARAM. В 32-х битной среде оба эти параметра имеют размер 32 бита (longword). В 16-битной Windows WPARAM - это 16 битное число (word), а LPARAM - 32-битное (longint).

Для отправки сообщений API Windows® содержит две функции:

function PostMessage( HWND hWnd, // handle of destination window
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
):BOOLEAN;

function SendMessage( HWND hWnd, // handle of destination window
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
): LRESULT;

Первая из них отправляет сообщение в очередь сообщений Windows® и немедленно возвращает управление. PostMessage возвращает TRUE, если вызов функции прошел успешно и FALSE в противном случае.

Функция SendMessage отличается от PostMessage тем, что, послав сообщение, она не возвратит управление до тех пор, пока сообщение не будет доведено до получателя.

Обе функции имеют одинаковые параметры: HWND - дескриптор окна, которому предназначается сообщение, UINT - сообщение, которое должно быть послано, WPARAM и LPARAM - параметры сообщения.

В следующем примере главной форме проекта посылается сообщение о закрытии приложения:

PostMessage(Handle,WM_QUIT,0,0);

В дополнение к функциям API Windows® VCL содержит метод Perform, который можно использовать для посылки сообщений любому окну VCL.

function Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;

Perform обходит систему передачи сообщений Windows® и направляет сообщение непосредственно механизму обработки данного окна. С использованием предыдущий пример будет выглядеть следующим образом:

Perform(WM_QUIT,0,0);

VCL имеет события примерно лишь для 20% наиболее часто используемых сообщений Windows®. У программиста может возникнуть необходимость обработать сообщения, для которых в VCL события не предусмотрены. Для обработки сообщений ОС, не имеющих соответствующих событий в Delphi есть ключевое слово message. С его помощью конкретный метод в коде программы может быть связан с любым сообщением Windows®. Когда окно приложения получает это сообщение вызывается соответствующий метод. Для реализации обработки сообщения на этом уровне необходимо:

1. Включить объявление метода для обработки сообщения в объявление класса, указав ключевое слово message и название сообщения, для обработки которого данный метод редназначен.

2. Включить определение метода в раздел implementation.

Приведем пример определения метода, обрабатывающего сообщение WM_ERASEBKGND:

Procedure WmEraseBkgnd(var Msg:tWMEraseBkgnd); message WM_ERASEBKGND;

Ключевое слово message указывает на то, что данный метод используется для обработки сообщения ОС, имя которого указано после этого ключевого слова: WM_ERASEBKGND. Следует также отметить, что параметр метода является записью типа tWMEraseBkgnd.

type TWMEraseBkgnd=record
Msg:Cardinal;
DC:HDC;
Unused:Longint;
Result:Longint;
end;

В VCL имеются записи для большинства сообщений Windows® (они определены в модуле Messages.pas). Именем записи является имя сообщения с префиксом t и без подчеркивания. Сам метод можно назвать как угодно, но приведенная выше форма является общепринятой. В этом методе может возникнуть необходимость вызвать обработчик сообщения, установленный по умолчанию. Для этого необходимо вызвать виртуальный метод класса tObject DefaultHandler:

procedure tObject.DefaultHandler(var Message); virtual;

Помимо нормальных сообщений Windows®, можно создать свое собственное сообщение. еализация и перехват определяемого пользователем сообщения идентичны обработке сообщений Windows®. Единственное отличие состоит в том, что это сообщение необходимо сначала определить:

Const My_Message = WM_USER + 1;

Эта строка объявляет пользовательское сообщение с именем My_Message.

Для обработки сообщений, определенных пользователем в качестве типа параметра обработчика сообщения следует использовать запись общего вида tMessage:

type tMessage = record
Msg:Cardinal;
WParam:Longint;
LParam:Longint;
Result:Longint;
end;

Здесь, как и во всех других определенных в VCL для сообщений записях, поле Msg определяет передаваемое сообщение, поле Result - результат действия обработчика. Уникальные для данной записи поля WParam и LParam содержат соответствующие параметры сообщения.

Для посылки определяемых пользователем сообщений можно использовать функции SendMessage, PostMessage, однако, предпочтительнее в данном случае использовать Perform.

Сокеты

Наиболее современным и даже "модным" является общение процессов на уровне сокетов. Популярность их обусловлена взрывным ростом интереса как пользователей, так и специалистов к Internet и всему, что связано с этой сетью.

Общепринятой и стандартизованной на международном уровне является семиуровневая модель структуры протоколов связи под названием интерфейс открытых систем (Open Systems Interface, OSI). На каждом из уровней — от первого, физического, до высших уровней представления и приложений — решается свой объем задач и используется свой инструментарий.

Сокеты находятся как раз на промежуточном, так называемом транспортном уровне семиуровневой структуры. "Под ним", на сетевом уровне, находится протокол IP (основа TCP/IP — Transmission Control Protocol/Internet Protocol). Над ним находятся протоколы сеансового уровня (сервисы), ориентированные на конкретные задачи — например, FTP (для передачи файлов), SMTP (почтовый), всем известный гипертекстовый протокол HTTP и другие. Использование сокетов, с одной стороны, позволяет абстрагироваться от частностей работы на нижних уровнях, с другой — решать широкий круг задач, недоступный специализированным протоколам.

С точки зрения своей сущности сокет — это модель одного конца сетевого соединения, со своими свойствами и возможностью читать и записывать данные. С точки зрения содержания — это прикладной программный интерфейс, входящий в состав разных операционных систем, в том числе Windows — начиная с версии 3.11. Последняя его реализация носит название WinSock 2.0. Прототипы функций содержатся в файле WINSOCK.PAS, поставляемом с Delphi.

API сокетов впервые появился в среде Unix и стал популярен вместе с (и благодаря) протоколом TCP/IP. Именно они являются строительным материалом, из которого построена сеть Internet. Но сокеты не обязательно базируются на TCP/IP, они могут базироваться на IPX/SPX и других протоколах.

Механизм соединения при помощи сокетов таков. На одной стороне создается клиентский сокет. Для инициализации связи ему нужно задать путь к серверному сокету, с которым предстоит установить соединение.

Путь в сети задается двумя параметрами: адресом или равноценным ему именем хоста, или просто хостом и номером порта. Хост — это система, в которой запущено приложение, содержащее сокет. Неверно приравнивать понятие "хост" или "адрес" к понятию "компьютер" — у компьютера может быть несколько сетевых устройств и несколько адресов. Адрес в сетях TCP/IP задается четверкой чисел в диапазоне 0..255, например, так: 192.168.99.1. Естественно, каждый адрес даже в рамках Internet уникален — за этим следит специальная организация. Имя хоста, как правило, — символьная строка, поставленная в соответствие адресу и записанная по правилам UNC, например http://www.microsoft.com. Взаимное соответствие между именами и адресами может осуществляться по-разному, в зависимости от масштаба сети и применяемой ОС. В Internet существует система имен доменов (DNS) — специальные серверы, хранящие и поддерживающие таблицы соответствия между символьным именем и адресом. Но в любом случае соединение по адресу быстрее, так как не нужно обращаться за дополнительной информацией.

В случае, если ваши клиент/серверные приложения отлаживаются на одной и той же машине, можно связать сокеты четырьмя способами:

· Указанием сетевого имени вашего компьютера (узнать его можно через апплет "Сеть" Панели управления)

· Указанием IP — адреса вашего компьютера (узнать его можно в свойствах протокола ТСР/IP: на машине должен стоять этот протокол и иметься постоянный IP-адрес)

· Указанием имени localhost, указывающего, что сервер находится на том же компьютере

· Указанием IP-адреса 127.0.0.1, указывающего на тоже самое

Номер порта — простое средство для поддержания одновременно нескольких связей между двумя хостами. Это число, обычно зарезервированное для протоколов более высокого уровня. Так, для протокола FTP выделен порт 21, SMTP — 25, популярная игра Quake II использует порт 27910 и т. п. Программист должен ознакомиться со списком уже закрепленных портов, прежде чем установит и использует свое значение.

С одной из двух вступающих в связь сторон запускается серверный сокет. Первоначально он находится в состоянии просушивания (listening), то есть ожидания связи. После получения запроса от другой стороны — клиента — устанавливается связь. Но в то же время создается новый сокет для продолжения прослушивания.

Естественно, в составе Delphi имеется полноценная поддержка сокетов. Еще в версии 2 появился заголовочный файл WINSOCK.PAS. Есть он и сейчас — для желающих использовать API WinSock напрямую. Мы же рассмотрим здесь компоненты TServerSocket и TClientSocket, имеющиеся в Delphi 4 на странице Internet Палитры компонентов.

Очень важным моментом в использовании сокетов является задание их типа — блокирующего (синхронного) и неблокирующего (асинхронного). По существу, работа с сокетами — не что иное, как операции ввода/вывода, которые, как мы знаем, также могут быть синхронными и асинхронными (отложенными). В первом случае при вызове функции ввода/вывода приложение блокируется до его окончания. Во втором — инициируется ввод/вывод и выполнение приложения сразу же продолжается; окончание ввода/вывода будет "ознаменовано" в системе возникновением некоторого события. В библиотеке WinSock 2.0 поддерживаются оба типа операций с сокетами; соответственно, в компонентах Delphi также можно установить нужный тип. Отвечают за него свойства serverType и clientType, о которых рассказано ниже.

Специфика компонентов TServerSocket и TClientSocket в том. что они являются "двухэтажными" надстройками над API сокетов. И у того, и у другого имеется свойство:

property Socket: TClientWinSocket;

у компонента TClientSocket и

property Socket: TServerWinSocket;

у компонента TServerSocket

Это свойство представляет собой объект — собственно оболочку сокета, со всеми функциями поддержки установления соединения, чтения и записи. азделение труда между ними такое—на уровне TServerSocket (TClientSocket) сосредоточены основные опубликованные свойства и события, обработку которых можно запрограммировать; на уровне TServerWinSocket (TClientWinSocket) следует искать функции, в том числе чтения и записи в сокет.

Объект TServerWinSocket

На уровне этого объекта ведется список соединений с клиентскими сокетами, содержащийся в свойстве:

property Connections [Index: Integer]: TCustomWinSocket;

Общее число соединений (и число элементов в свойстве connections) равно значению свойства:

property ActiveConnections: Integer;

Этим списком и счетчиком удобно пользоваться для рассылки всем клиентам какой-нибудь широковещательной информации, например:

for i:=0 to ServerSocket.Socket.ActiveConnections-1 do
ServerSocket.Socket.Connections[i].SendText('Hi! ');

Тип сервера (блокирующий/неблокирующий) задается свойством

type TServerType = (stNonBiocking, stThreadBiocking);
property ServerType: TServerType;

Поскольку сервер, который блокируется каждым чтением/записью, представить себе трудно, разработчики фирмы Inprise пошли таким путем. Блокирующий режим заменен режимом stThreadBlocking. В этом случае при установлении каждого нового соединения запускается отдельный программный поток3 (объект класса TServerclientThread). Он отвечает за связь с отдельным клиентом, и его блокировка не влияет на работу остальных соединений.

Если вы не хотите порождать TServerclientThread, а хотите описать свой класс потока и использовать его для работы с сокетом, вам нужно создать обработчик события:

property OnGetThread: TGetThreadEvent;
type TGetThreadEvent = procedure (Sender: TObject;
ClientSocket: TServerClientWinSocket; var SocketThread: TServerCiientThread) of object;

В отличие от stThreadBlocking, тип stNonBlocking своим поведением ничем не отличается от описанного выше — операции происходят асинхронно, и программист должен лишь описать реакцию на события, возникающие в момент их окончания.

Как известно, создание и уничтожение нового программного потока влечет за собой определенные системные накладные расходы. Чтобы избежать этого, в рассматриваемом объекте ведется кэш потоков. По завершении соединения потоки не уничтожаются, а переводятся в состояние ожидания нового соединения.

Свойство: property ThreadCacheSize: Integer;

задает количество свободных потоков, которые могут находиться в готовности для установления соединения с клиентом. Это количество должно рассчитываться в зависимости от интенсивности и продолжительности контакта с клиентами. Лишние потоки поглощают системные ресурсы, в первую очередь память и процессорное время. Чтобы оптимизировать использование кэша свободных потоков, полезно поинтересоваться значением двух свойств:

property ActiveThreads: Integer;

property IdieThreads: Integer;

показывающих число активных (занятых обслуживанием клиентов) и простаивающих (ожидающих) потоков соответственно.

Старт и завершение потока, работающего с сокетом, обрамлены событиями:

property OnThreadStart: TThreadNotifyEvent;
property OnThreadEnd: TThreadNotifyEvent;
type TTnreadNotifyEvent=procedure(Sender: TObject;
Thread: TServerClientThread) of object;

Чтобы избежать ситуаций тупиков или гонок при работе с сокетами, имеются два метода:

procedure Lock;
procedure Unlock;

Если вами предусмотрен код, который может вызвать проблемы в многозадачной среде, заключите его между вызовами методов Lock и unlock — на это время остальные потоки, работающие с сокетами, будут блокированы.

Методы чтения и записи для блокирующего и неблокирующего режима существенно отличаются. ассмотрим сначала те, что предназначены для неблокирующего (асинхронного) режима.

Средства для организации чтения представлены группой из трех методов:

function ReceiveLength: Integer;

возвращает число байт, которые могут быть приняты в ответ на оповещение клиента о передаче

function ReceiveText: string;

возвращает прочитанную из сокета текстовую строку

function ReceiveBuf(var Buf; Count:Integer): Integer;

возвращает данные, прочитанные из сокета в буфер Buf, в количестве count байт

Аналогично, методы:

function SendBuf(var Buf; Count: Integer): Integer;

procedure SendText(const S: string);

function SendStream (AStream: TStream) : Boolean;

посылают клиенту буфер, текстовую строку и поток данных. В дополнение к этому метод:

function SendStrearoThenDrop (AStream: TStream): Boolean;

посылает клиенту поток данных и завершает соединение.

Передаваемый в качестве параметра последних двух функций поток данных AStream переходит "под надзор" объекта TServerWinsocket и удаляется им по мере пересылки. Программист не должен предпринимать попыток удалить AStream после вызова методов SendSrteam или SendSrteamThenDrop.

При помощи метода:

function GetClientThread(ClientSocket: TServerClientWinSocket): TServerClientThread;

можно получить указатель на поток, занимающийся обслуживанием конкретного сокета.

События:

property OnClientConnect;
property OnClientDisconnect;
property OnClientRead;
property OnClientWrite;

имеют одинаковый тип:

TSocketNotifyEvent=procedure(Sender: TObject;
Socket: TCustomWinSocket) of object;

Они происходят при соединении/отключении от клиента, а также при чтении и записи. Если произошла ошибка, возникает событие:

property OnClientError; TSocketErrorEvent;
type
TErrorEvent = (eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect, eeAccept);
TSocketErrorEvent = procedure (Sender: TObject;
Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent;
var ErrorCode: Integer) of object;

Параметры его имеют следующее назначение. ErrorEvent указывает на тип операции, во время которой произошла ошибка. При этом ErrorCode содержит код ошибки Windows. Если вы сами обработали ошибку и не хотите дальнейших действий по ее обработке со стороны системы, нужно установить параметр ErrorCode в 0.

Компонент TServerSocket

Самое главное свойство этого компонента — уже упоминавшаяся ссылка на объект:

property Socket: TServerWinSocket;

Именно через него доступны все функциональные возможности сокета. Компонент же создан только для того, чтобы опубликовать необходимые свойства и события. В нем имеются свои события OnclientConnect, OnClientDisconnect, OnClientRead, OnClientWrite, OnClientError, но они не самостоятельны, а только отсылают к соответствующим событиям объекта TServerWinSocket. Также обстоит дело и со свойствами serverType и ThreadCacheSize.

Дополнительно в компоненте предусмотрены события:

property OnListen: TSocketNotifyEvent;

происходит после того, как заданы адрес и порт сокета и перед тем, как он включается в режим прослушивания (готовности к соединению)

property OnAccept: TSocketNotifyEvent;

происходит непосредственно после установки соединения

Свойство property Active: Boolean;
отвечает за состояние сокета. Для клиентского сокета изменение его значения соответствует подключению/отключению от сервера. Для серверного — включение/выключение состояния прослушивания. Использование этого свойства равносильно применению следующих методов:

procedure Open;

procedure Close;

Свойство property Service: string;
служит для идентификации предназначения сокета. Здесь должно храниться символьное имя сервиса, для которого используется сокет (ftp, http, telnet и др.)

Объект TClientWinSocket

Многие из событий и методов этого объекта уже описаны выше (см. объект TServerwinSocket), так как они имеют общего предка. Но есть и различия, требующие комментария. Как и серверный, клиентский сокет может быть двух типов:

type TCiientType = (ctNonBlocking, ctBlocking);
property ClientType: TCiientType;

В отличие от сервера, в блокировке клиента большой беды нет. Если установлен режим ctBlocking, клиентское приложение блокируется до завершения операции. В режиме ctNonBiocking операции выполняются асинхронно.

Компонент TClientSocket

Основное внимание при рассмотрении этого компонента обратим на логику событий, происходящих при подключении клиентского сокета к серверу. Она такова:

1. Вызывается метод open (или свойство Active устанавливается в True).

2. Перед началом инициализации происходит событие

property onLookup: TSocketNotifyEvent;.

В этот момент еще можно поменять свойства объекта TClieniwinSocket: адрес, номер порта и т. п.

3. Сокет полностью инициализируется и начинает поиск. Когда серверный сокет обнаружен, происходит событие

property onConneciing: TSocketNotifyEvent;.

4. Когда клиентский запрос удовлетворен сервером и установлено соединение, происходит событие

property OnConnect: TSocketNotifyEvent;

Проиллюстрируем сказанное на примере пересылки информации о дате и времени. Процесс подключения к серверу выглядит таким образом:

procedure TClientForm.FileConnectltemClick(Sender: TObject);
Begin
if ClientSocket.Active then ClientSocket.Active := False;
if InputQuery('Сервер', 'Адрес (имя)', Server) then
if Length(Server)>0 then
with ClientSocket do begin
Host := Server;
Active := True;
end;
End;

После установления соединения клиент реагирует на событие onClientRead:

procedure TCiientFom.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
var s: string;
Begin
s:= Socket.ReceiveText;
if ((s[l]='T') and (TimeSpeedButton.Down)) then
TimeSpeedButton.Caption:=Copy(s, 2, Length(s))
else if ((s[l]='M') and (MemSpeedButton. Down)) then
KemSpeedButton.Caption:=Copy(s, 2, Length (s));
End;

В серверном приложении сокет устанавливается в активное состояние (прослушивание) при запуске программы. Все подключившиеся клиенты автоматически заносятся как элемент списка (свойство connections). Саму информацию о дате и времени сервер рассылает по таймеру в виде отформатированных текстовых строк:

procedure TServerForm.TimerITimerlSender: TObject);
var i: Integer;
s: string;
ms : TMemoryStatus;
Begin
with ServerSocket.Socket do
for i:=0 to ActiveCcnnections-I do
Connections[i].SendText('T'+TimeToStr(Now));
GlobaiMemoryStatus(ms);
s:=Format('%1OdK',[(ms.dwAvaiiPageFile + ms.dwAvaiiPhys) div 1024]); with ServerSocket.Socket do
for i:=0 to ActiveConnections-I do
Connections [ i ] . SendText ( ' M' +s ) ;
End;

Сервер может отреагировать на сообщение от клиента. Ответ следует отправлять через параметр socket произошедшего события onClientRead:

procedure TServerForm.ServerSocketClientRead (Sender: TObject;
Socket: TCustomWinSocket);
Begin
Memo1.Lines.Add(Socket. ReceiveText );
Socket.SendText( ' I am understand' );
End;

К сокетам проявляют интерес многие разработчики, что можно объяснить их универсальностью и широким распространением. Если вы не нашли чего-то для вас необходимого в компонентах TClientSocket и TServerSocket, или наоборот — сочли их слишком сложными в применении, вы можете использовать компонент TPowersock, разработанный компанией NetMasters. Он находится также на странице Internet Панели инструментов.



2020-02-03 154 Обсуждений (0)
Опция заполнения класса 0.00 из 5.00 0 оценок









Обсуждение в статье: Опция заполнения класса

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы...
Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (154)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.01 сек.)