Установка соединения с каналом на стороне сервера




После того как серверный процесс создал канал, он может перейти в режим соединения с клиентским процессом. Соединение со стороны сервера выполняется с помощью функции ConnectNamedPipe. Прототип которой представлен ниже:

BOOL ConnectNamedPipe(

HANDLE hNamedPipe, //идентификатор именованного канала

LPOVERLAPPED lpOverlapped); // адрес структуры OVERLAPPED

Первый параметр - дескриптор канала, полученный от функции CreateNamedPipe().

Второй параметр используется только для огранизации асинхронного обмена данными через канал. При использовании синхронныч операции значение этого параметра можно задать как NULL.

В случае успеха функция ConnectNamedPipe()возвращает значение TRUE, а при ошибке - FALSE. Код ошибки можно получить с помощью функции GelLastError().

Для канала, созданного в синхронном блокирующем режиме (т.е. с использованием константы PIPE_WAIT), функция ConnectNamedPipe() переводит серверный процесс в состояние ожидания соединения с клиентским процессом.

Если канал создан в синхронном неблокирующем режиме, функция ConnectNamedPipe() немедленно возвращает управление с кодом TRUE, если только клиент был отключен от данной реализации канала или не подключался ранее и возможно новое подключение этого клиента. В противном случае возвращается значение FALSE.

Дальнейший анализ необходимо выполнять с помощью функции GetLastError(). Эта функция может вернуть значение:

ERROR_PIPE_LISTENING - к серверу еще не подключен ни один клиент,

ERROR_PIPE_CONNECTED - клиент уже подключен к серверу,

ERROR_NO_DATA - предыдущий клиент отключился от сервера, но

клиент еще не закрыл соединение.

ПРИМЕР

 

BOOL fConnected;

fConnected = ConnectNamedPipe(hPipe, NULL);

//Ожидание клиента

if (!fConnected)

{ printf ("Ошибка при подключении клиента\n";

}

 

Установка соединения с каналом на стороне клиента

Для создания канала клиентский процесс может воспользоваться функцией CreateFile(), которая предназначена для работы с файлами,устройствами, каналами (подробно см. раздел ОС_Допол_Работа сфайлами.rtf).

В случае успешного завершения функция CreateFile() возвращает идентификатор созданного или открытого файла/каталога или канала.

При ошибке возвращается значение INVALID_HANDLE_VALUE. Код ошибки можно определить при помощи функции GetLastError().

 

В том случае, если файл уже существует и были указаны константы CREATE_ALWAYS или OPEN_ALWAYS, функция CreateFile() не возвращает код ошибки, но функция GetLastError() возвращает значение ERROR_ALREADY_EXISTS.

 

Функция WaitNamedPipe

С помощью функции WaitNamedPipe() процесс может выполнять ожидание момента, когда канал Pipe будет доступен для соединения:

BOOL WaitNamedPipe(

LPCTSTR lpszPipeName, // имя канала Pipe

DWORD dwTimeout); // время ожидания в миллисекундах

Помимо численного значения времени в миллисекундах, можно указать в этом параметре одну из следующих констант:

Константа Описание  
  NMPWAIT_WAIT_FOREVER Ожидание выполняется бесконечно долго
  NMPWAIT_USE_DEFAULT_WAIT Ожидание выполняется в течении периода времени, указанного при вызове функции CreateNamedPipe
         

 

ПРИМЕР

 

HANDLE hPipe;

CHAR chBuf[512];

DWORD cbRead, cbWritten, dwMode;

LPTSTR lpPipename = "\\\\.\\pipe\\mypipe";

 

while (1) // Открытие поименованного канала

{ hPipe = CreateFile(

lpPipename, // pipe name

GENERIC_READ | GENERIC_WRITE,// доступ на чтение/запись

0, // нет разрешений для других

// процессов

NULL, // атрибуты безопасности

OPEN_EXISTING, // открыть уже существ. канал

0, // флаги и атрибуты по умолч.

NULL // нет файла-шаблона

);

 

if (hPipe == INVALID_HANDLE_VALUE)

{ printf ("hPipe = INVALID_HANDLE_VALUE \n");

return;

}

if (GetLastError()!= ERROR_PIPE_BUSY)

{ printf ("Не могу открыть канал \n");

return;

// Выход, если ошибка!=ERROR_PIPE_BUSY(канал занят)

}

// Если все реализации канала заняты, ждем 30 секунд, затем // опять выполняем попытку соединения.

if (!WaitNamedPipe(lpPipename, 30000))

{ printf ("Не могу открыть канал в течение 30 сек\n";

}

}

 

5. Запись данных в канал и чтение данных из канала

Запись данных в открытый канал выполняется с помощью функции WriteFile(), аналогично записи в обычный файл, например:

HANDLE hNamedPipe;

DWORD cbWritten;

char Buf1[256];

WriteFile (hNamedPipe, szBuf, strlen(szBuf) + 1, &cbWritten, NULL);

параметр cbWritten используется для определения количества байт данных, действительно записанных в канал. И, наконец, последний параметр задан как NULL, поэтому запись будет выполняться в синхронном режиме. Если канал был создан для работы в блокирующем режиме, и функция WriteFile работает синхронно (без использования вывода с перекрытием), то эта функция не вернет управление до тех пор, пока данные не будут записаны в канал.

Чтение данных из канала выполняется функцией ReadFile():

HANDLE hNamedPipe;

DWORD cbRead;

char Buf1[256];

ReadFile (hNamedPipe, szBuf, 512, &cbRead, NULL);

Данные, прочитанные из канала hNamedPipe, будут записаны в буфер szBuf, имеющий размер 512 байт. Количество действительно прочитанных байт данных будет сохранено функцией ReadFile в переменной cbRead. Так как последний параметр функции указан как NULL, используется синхронный режим работы без перекрытия.

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

- подключение к каналу с помощью функции CreateFile;

- выполнение операций чтения или записи такими функциями как ReadFile или WriteFile;

- отключение от канала функцией CloseHandle.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-11-01 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: