Подключение клиентов и серверов именованных каналов
Подключение клиентов и серверов именованных каналов
Операции по подключению клиентов и серверов к именованным каналам выполняются в описанном ниже порядке. Сначала мы рассмотрим последовательность операций, выполняемых сервером, при помощи которых сервер создает соединение с клиентом, взаимодействует с клиентом до тех пор, пока тот не разорвет соединение (вынуждая функцию ReadFile вернуть значение FALSE), разрывает соединение на стороне сервера, а затем образует соединение с другим клиентом:
/* Последовательность операций при создании соединения с использованием именованного канала для сервера. */
hNp = CreateNamedPipe("\\.\pipe\my_pipe", …);
while (… /* Цикл продолжается вплоть до завершения работы сервера.*/) {
ConnectNamedPipe(hNp, NULL);
while (ReadFile(hNp, Request, …) {
…
WriteFile(hNp, Response, …);
}
DisconnectNamedPipe(hNp);
}
CloseHandle(hNp);
Перейдем к рассмотрению последовательности операций, выполняемых клиентом, в которой клиент прекращает выполнение после завершения работы, давая возможность подключиться к тому же экземпляру именованного канала другому клиенту. Как показано ниже, клиент может соединиться с сервером в сети, если ему известно сетевое имя сервера (ServerName):
/* Последовательность операций при создании соединения с использованием именованного канала для клиента. */
WaitNamedPipe("\\ServerName\pipe\my_pipe", NMPWAIT_WAIT_FOREVER);
hNp = CreateFile("\\ServerName\pipe\my_pipe", …);
while (…/*Цикл выполняется до тех пор, пока не прекратятся запросы.*/ {
WriteFile(hNp, Request, …);
…
ReadFile(hNp, Response);
}
CloseHandle (hNp); /* Разорвать соединение с сервером. */
Обратите внимание, что клиент и сервер состязаются за ресурсы. Прежде всего, клиентский вызов функции WaitNamedPipe завершится ошибкой, если именованный канал к этому моменту еще не был создан сервером; для краткости тестирование успешности выполнения в нашем примере опущено, однако оно включено в примеры программ, доступные на Web-сайте. Далее, в редких случаях вызов CreateFile может быть выполнен еще до того, как сервер вызовет функцию ConnectNamedPipe. В этом случае функция ConnectNamedPipe вернет серверу значение FALSE, однако взаимодействия посредством именованного канала по-прежнему будет функционировать надлежащим образом.
Экземпляр именованного канала является глобальным ресурсом, поэтому, когда клиент разрывает соединение с сервером, к нему может подключиться другой клиент.