Неблокирующее событие ConnectNamedPipe не получает сигнал

Я начинаю с именованных каналов и должен использовать их для IPC между двумя локальными процессами. У меня есть и сервер, и клиентский процесс, использующий канал в режиме перекрытия без блокировки.

Все работает нормально (сервер успешно получает строку, отправленную клиентом), за исключением того, что событие, переданное ConnectNamedPipe () через структуру OVERLAPPED, не получает сигнал, как ожидалось (сигнал при подключении клиента).

В то время как сервер заблокирован при вызове WaitForSingleObject (), клиентский процесс, подключенный к каналу, отправил свои данные и завершился, но событие не получает сигнал. Что мне не хватает?

Код сервера:

HANDLE hPipe = ::CreateNamedPipeW(
L"\\\\.\\pipe\\ThePipe",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT,
1,
4096,
4096,
100,
nullptr);

OVERLAPPED ov = {0};
ov.hEvent = ::CreateEventW(nullptr, TRUE, FALSE, nullptr);

BOOL retVal = ::ConnectNamedPipe(hPipe, &ov);

if (retVal == 0)
{
DWORD err = ::GetLastError();
if (err == ERROR_IO_PENDING)
{
::WaitForSingleObject(ov.hEvent, 30000);
}
if (err == ERROR_PIPE_LISTENING)
{
::WaitForSingleObject(ov.hEvent, 30000);    // this blocks until time-out???
}
}

5

Решение

Вы не должны использовать (не рекомендуется) PIPE_NOWAIT вместе с перекрывающимся режимом. PIPE_NOWAIT марки ConnectNamedPipe немедленно вернуться ERROR_PIPE_LISTENING если клиент не подключен; перекрывающийся ввод-вывод просто не происходит, и ожидание события бесполезно.

Либо вы установили PIPE_NOWAIT и периодически опрашивать канал до успеха, или вы установите FILE_FLAG_OVERLAPPED и использовать событие, чтобы проверить / дождаться завершения.

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]