З'єднання клієнтів з іменованих каналом

Перш ніж з'єднуватися з іменованих каналом, клієнт повинен визначити чи доступний будь-якої екземпляр цього каналу для з'єднання. З цією метою клієнт повинен викликати функцію:

LPCTSTR lpNamedPipeName, // покажчик на ім'я каналу

DWORD nTimeOut // інтервал очікування

яка в разі успішного завершення повертає значення TRUE, а в разі невдачі - FALSE. Параметри цієї функції мають такі значення.

Параметр lpNamedPipeName вказує на рядок, яка повинна мати вигляд

тут позначає ім'я комп'ютера, на якому виконується сервер іменованого каналу.

Параметр nTimeOut задає часовий інтервал протягом якого клієнт чекає зв'язок з сервером. Цей часовий інтервал визначається в мілісекундах або може дорівнювати одному з наступних значень:

· NMPWAIT_USE_DEFAULT_WAIT інтервал часу очікування визначається значенням параметра nDefaultTimeOut, який задається в функції CreateNamedPipe,

· NMPWAIT_WAIT_FOREVER нескінченне час очікування зв'язку з іменованих каналом.

Зробимо два важливих зауваження щодо роботи функції WaitNamedPipe. По-перше, якщо не існує примірників іменованого каналу з ім'ям lpNamedPipe, то ця функція негайно завершується невдачею, незалежно від часу, визначений параметром nTimeOut. По-друге, якщо клієнт з'єднується з каналом до виклику сервером функції ConnectNamedPipe, то функція WaitNamedPipe повертає значення FALSE і функція GetLastError поверне код ERROR_PIPE_CONNECTED. Тому функцію WaitNamedPipe потрібно викликати тільки після з'єднання сервера з каналом за допомогою функції ConnectNamedPipe.

Після того як виявлений вільний екземпляр каналу, для того щоб встановити зв'язок з цим каналом клієнт повинен викликати функцію

LPCTSTR lpFileName, // покажчик на ім'я каналу

DWORD dwDesiredAccess. // читання або запис в канал

DWORD dwShareMode, // режим спільного використання

LPSECURITY_ATTRIBUTES lpSecurityAttributes, // атрибути захисту

DWORD dwCreationDisposition, // прапор відкриття каналу

DWORD dwFlagsAndAttributes, // прапори і атрибути

HANDLE hTemplateFile // додаткові атрибути

яка в разі успішного завершення повертає дескриптор іменованого каналу, а в разі невдачі - значення INVALID_HANDLE_VALUE.

Параметри функції CreateFile можуть набувати наступних значень, якщо ця функція використовується для відкриття іменованого каналу.

Параметр lpFileName повинен вказувати на ім'я каналу, яке повинно бути задано в тому ж форматі, що і в функції WaitNamedPipe.

Параметр dwDesiredAccess може приймати одне з наступних значень:

· 0 дозволяє отримати атрибути каналу,

· GENERIC_READ дозволяє читання з каналу,

· GENERIC_WRITE дозволяє запис в канал.

Слід зазначити, що функція CreateFile завершується невдачею, якщо доступ до іменовані канали, заданий цими значеннями, не відповідає значенням параметра dwOpenMode в функції CreateNamedPipe. Крім того, в цьому параметрі програміст може визначити стандартні права доступу до іменовані канали. За більш детальною інформацією з цього питання потрібно звернутися до MSDN.

Параметр dwShareMode визначає режим спільного використання іменованого каналу і може приймати значення 0, яке забороняє спільне використання іменованого каналу або будь-яку комбінацію наступних значень:

· FILE_SHARE_READ дозволяє спільне читання з каналу,

· FILE_SHARE_WRITE дозволяє спільний запис в канал.

Параметр lpSecurityAttributes задає атрибути захисту іменованого каналу.

Для іменованого каналу параметр dwCreationDisposition має дорівнювати значенню OPEN_EXISTING, так як клієнт завжди відкриває існуючий іменований канал.

Для іменованого каналу параметр dwFlagsAndAttributes можна задається рівним 0, що визначає прапори і атрибути за замовчуванням. Детальну інформацію про значеннях цього параметра дивись в MSDN.

Значення параметра hTemplateFile задається рівним NULL.

Зробимо наступні зауваження щодо роботи з функцією CreateFile в разі її використання для відкриття доступу до іменовані канали. По-перше, незважаючи на те, що функція WaitNamedPipe може успішно завершитися, наступний виклик функції CreateFile може завершитися невдачею через наступні випадки:

між викликами цих функцій сервер закрив канал,

між викликами функцій інший клієнт зв'язався з екземпляром цього каналу.

Для запобігання останньої ситуації сервер повинен створювати новий екземпляр іменованого каналу після кожного успішного завершення функції ConnectNamedPipe або створити відразу кілька примірників іменованого каналу. По-друге, якщо заздалегідь відомо, що сервер викликав функцію ConnectNamedPipe, то функція CreateFile може викликатися без попереднього виклику функції WaitNamedPipe.

Крім того, слід зазначити, що якщо клієнт працює на тій же машині, що і сервер і використовує для відкриття іменованого каналу в функції CreateFile ім'я сервера у вигляді:

то файлова система іменованих каналів (NPFS) відкриває цей іменований канал в режимі передачі даних потоком. Щоб відкрити іменований канал в режимі передачі даних повідомленнями, потрібно задавати ім'я сервера у вигляді:

Відзначимо один момент, який стосується зв'язку сервера з клієнтом іменованого каналу. Може виникнути така ситуація, що сервер викликав функцію ConnectNamedPipe, а клієнта, який хоче зв'язатися з іменованих каналом, не існує. В цьому випадку серверний додаток буде заблоковано. Щоб мати можливість обробити таку ситуацію, функцію ConnectNamedPipe слід викликати в окремому потоці серверного додатка. Тоді для розблокування серверного додатка можна викликати функцію для зв'язку клієнта з іменованих каналом з іншого потоку.