Я изучаю именованные каналы и играл с примерами клиента и сервера именованных каналов из документа MSDN:
Сервер именованных каналов
Клиент Named Pipe
Я изменил клиента, чтобы я мог вводить сообщения на консоль и отправлять их на сервер, где он отображает сообщение и отправляет ответ. По сути, я добавил цикл, который начинается после вызова SetNamedPipeHandleState () и заканчивается перед вызовом CloseHandle () (то есть открытие и закрытие происходят вне цикла, поэтому я использую один и тот же дескриптор канала в цикле).
У меня вопрос: если я убью клиента (закрыв его или завершив через диспетчер задач), сможет ли серверная сторона обнаружить отключение?
Я пытался использовать GetNamedPipeHandleState (), надеясь, что он вернет ошибку, и вызов GetLastError () вернет ERROR_PIPE_NOT_CONNECTED, но это не так. Из-за того, как настроен этот сервер, мне пришлось сделать это в функции CompletedReadRoutine и создать «контролируемый» сбой. Я сделал с точкой останова на CompletedReadRoutine на сервере:
- запустил сервер
- запустил клиент
- отправил сообщение через клиента (достигает точки останова на сервере здесь)
- убил клиента
- Шагнул к GetNamedPipeHandleState
Вызов GetNamedPipeHandleState () успешно завершается, поэтому мне никогда не удавалось выполнить вызов GetLastError (). Когда он достигает вызова WriteFileEx, он завершается неудачно, и вызов GetLastError в этот момент возвращает ERROR_NO_DATA.
Глядя на функции конвейера, я не вижу ничего другого, что могло бы помочь здесь. Я что-то пропустил или клиентское отключение просто не обнаружено.
Единственное, о чем я могу думать, это собирать pid подключающихся клиентов (через GetNamedPipeClientProcessId) и раскручивать сторожевые потоки, чтобы проверить, живы ли они. Хотя одно лишь размышление о том, как это сделать, вызывает у меня чувство пауков.
Есть ли способ обнаружить отключенных клиентов при использовании именованных каналов?