

| стрелялки |
| спорт |
| драки |
| стратегии |
| гонки |
| логические |
| азартные |
| аркады |
| эротические |
| фильмы онлайн |
| Пример простейшего компонента-сервера именованного канала |
|
Применим наши знания на практике. Следуя славным традициям ООП, предлагаю инкапсулировать сервер именованного канала в новый класс TPipeServer = class(THandleStream). unit srvpipe; interface uses Windows, Classes, SysUtils; type TPipeServer=class(THandleStream) private fBufSize : cardinal; //поле, хранящее размер входного и выходного буферов public property BufSize : cardinal read fBufSize; constructor Create(PipeName : string; BufferSize : cardinal); destructor Destroy; function Connect : boolean; //соединение с клиентом procedure Disconnect; //разрыв соединения function WriteData(const Buf) : integer; //метод передачи данных function ReadData (var Buf) : Integer; //метод получения данных end; Прежде чем перейти к секции реализации кода, прокомментируем описание создаваемого класса TPipeServer. За основу мы вновь принимаем подготовленный в Borland класс THandleStream. Напомню, что он обладает своим дескриптором (property Handle : THandle) и минимальными, но в нашем случае достаточными, функциональными возможностями для работы с разделяемым ресурсом. Для обеспечения работы с экземпляром канала нам потребуется научить класс следующим операциям: 1. Создавать именованный канал - конструктор Create(). 2. Разрушать канал - деструктор Destroy(). 3. Производить соединение с клиентом - метод Connect(). 4. Отключать клиента - метод Disconnect(). 5. Передавать данные - метод WriteData(). 6. Получать данные - метод ReadData(). Теперь переходим к разделу implementation модуля и сразу знакомимся с конструктором класса: constructor TPipeServer.Create(PipeName: string; BufferSize: cardinal); var SD : TSecurityDescriptor; SA : TSecurityAttributes; begin InitializeSecurityDescriptor(@SD,SECURITY_DESCRIPTOR_REVISION); SA.nLength:=SizeOf(TSecurityAttributes); SA.lpSecurityDescriptor:=@SD; SA.bInheritHandle:=True; fHandle:=CreateNamedPipe(PAnsiChar(PipeName), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE or PIPE_READMODE_BYTE or PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BufferSize, BufferSize, 600, @SA); fBufSize:=BufferSize; //запоминаем назначенный размер буферов в поле класса if fHandle=INVALID_HANDLE_VALUE then raise EOSError.Create(SysErrorMessage(GetLastError())); end; Чтобы максимально упростить код, в конструктор передаются всего два аргумента: имя канала PipeName и размер входного и выходного буферов именованного канала - BufferSize. В остальном формируем канал следующим образом: канал дуплексный (PIPE_ACCESS_DUPLEX), работает потоком байт (PIPE_TY-PEBYTE и PIPEREADMODEBYTE); функции ввода/вывода не возвращают управление программе до своего завершения (PIPEWAIT); количество экземпляров не ограничено (PIPEUNLIMITEDINSTANCES). |
