.
Tuesday 22nd of May 2012    

Информация

Счетчики

Голосование

Лучшая марка телефона
 

Реклама

фильмы онлайн

фильмы онлайн


Процедура разрыва связи с клиентом
загрузка...

В первых строках метода инициируем структуру TSecurityAttributes, чтобы предоставить возможность обращаться к каналу клиентским процессам, не обладающим правами администратора. Затем создаем экземпляр канала и сохраняем во внутреннем поле fBufSize размер буферов.

Деструктор класса рассмотрим совместно с методом отключения клиента от канала.

procedure TPipeServer.Disconnect; begin

FlushFileBuffers(Handle); //отправка оставшихся данных

DisconnectNamedPipe(Handle); //отключение клиента от канала

end;

destructor TPipeServer.Destroy; begin

Disconnect; //разрыв связи с клиентом

CloseHandle(Handle); //уничтожение экземпляра потока

end;

Процедура разрыва связи с клиентом включает вызов двух методов. Метод FlushFileBuffers() принудительно заставляет операционную систему записать в ресурс все изменения, и только после этого мы вызываем метод, отключающий клиент. Прежде чем приступить к разрушению канала, деструктор класса вызовет метод Disconnect().

Метод Connect() предназначен для подключения клиента к свободному каналу:

function TPipeServer.Connect : boolean;

var ErrorCod : cardinal;

begin

Result:=ConnectNamedPipe(Handle, nil); if Result=false then begin

ErrorCod:=GetLastError();

if ErrorCod = ERROR_PIPE_CONNECTED then Result:=true else raise EOSError.Create(SysErrorMessage(GetLastError()));

end; end;

Для подключения клиентского приложения к освободившемуся каналу вызывается метод ConnectNamedPipe(). В случае успешного соединения функция вернет true.

Для осуществления операций ввода/вывода реализованы простейшие методы ReadData() и WriteData(), готовые читать и передавать данные любого типа.

function TPipeServer.ReadData(var Buf): Integer; begin

Result:=Read(Buf,BufSize); end;

function TPipeServer.WriteData( const Buf): Integer; begin

Result:=Write(Buf,BufSize); end;

Пример простейшего компонента-клиента именованного канала

Дабы никто не мог упрекнуть нас в непоследовательности, клиент именованных каналов также построим в виде потомка THandleStream. В клиенте предусмотрены:

1. Конструктор, создающий именованный канал с именем PipeName.

2. Деструктор.

3. Методы чтения и записи. Обратите внимание, что для ожидания завершения операции в них применяются объекты синхронизации ReadEvent

и WriteEvent.

unit clntpipe; interface

uses Windows, Classes, SysUtils, SyncObjs;

type TPipeClient=class(THandleStream) protected

ReadOverlap,WriteOverlap : TOverlapped; //для асинхронной передачи данных ReadEvent, WriteEvent : TEvent; //объекты синхронизации - события

private

fInBufSize, fOutBufSize : cardinal; //поля с размерами буферов

public

property InBufSize : cardinal read fInBufSize; property OutBufSize : cardinal read fOutBufSize; constructor Create(PipeName : string); destructor Destroy;

function WriteData(const Buf) : integer; function ReadData ( var Buf) : Integer; end;

implementation

{ TPipeClient }

constructor TPipeClient. Create(PipeName : string);

var Flags : cardinal; begin

{раздельные объекты синхронизации для операций чтения и записи} ReadEvent :=TEvent.Create(nil,True,True,#0); WriteEvent:=TEvent. Create(nil,True, True,#0);

//структура OVERLAPPED

ReadOverlap.hEvent :=ReadEvent.Handle; WriteOverlap.hEvent:=WriteEvent.Handle;

fHandle:=CreateFile(pAnsiChar(PipeName),

GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

if (fHandle<>INVALID_HANDLE_VALUE) and (fHandle>0) then //узнаем основные характеристики канала

GetNamedPipeInfo(fHandle, Flags, @fInBufSize, @fOutBufSize, nil) else //если вызов метода завершился неудачей RaiseLastOSError;

end;

destructor TPipeClient.Destroy; begin

ReadEvent.Destroy; WriteEvent.Destroy; CloseHandle(Handle); end;

function TPipeClient.ReadData(var Buf): Integer;

var BytesToRead, BytesRead : cardinal;

begin

//если попытка чтения завершилась неудачно

if ReadFile(Handle,Buf,BytesToRead,BytesRead,@ReadOverlap)=false then //если код ошибки - "операция продолжается", то ожидаем окончания if GetLastError=ERROR_IO_PENDING then ReadEvent.WaitFor(INFINITE);

//получаем результат асинхронной операции

GetOverlappedResult(Handle,ReadOverlap,BytesRead,false);

Result:=BytesRead;

end;

function TPipeClient.WriteData(const Buf): Integer;

var BytesToWrite, BytesWrite : cardinal;

begin

If WriteFile(Handle,Buf,BytesToWrite,BytesWrite,@WriteOverlap)=false then if GetLastError=ERROR_IO_PENDING then WriteEvent.WaitFor(INFINITE);

GetOverlappedResult(Handle, WriteOverlap, BytesWrite, false);

Result:=BytesWrite;

end;

end.


загрузка...
 

Самое популярное:

Наши партнеры

bottom

карта сайта