Итак, у меня есть метод обслуживания, который использует io_service::poll()
для обработки любых текущих готовых событий чтения / записи:
void Foo::service()
{
io.poll(); // boost::asio::io_service
if (socket.is_open())
if (socket.available())
notifyReadyToRead();
else
notifyReadyToWrite();
}
Тем не менее, я также хотел бы вызвать поведение, если удаленный сокет закрывается (изящно или иначе). Я знаю, что Winsock может справиться с этим, так как в этом случае он вызывает сетевое событие. Однако, как я вижу, в гнездах Boost Asio нет встроенной поддержки.
Я попытался прочитать и записать нулевой байтовый пакет в сокет, чтобы проверить его на наличие ошибок, но кажется, что реализация просто успешно завершится, если вы передадите его boost::asio::buffer(socket, 0)
без фактической проверки сокета.
Я также слышал, что оставление операции чтения с зависанием может сработать, но я не уверен, как управлять этим, в то же время позволяя регулярно boost::asio::read
и операции ‘boost :: asio :: write` для правильной работы.
Наконец, добавление операции ping в протокол уровня приложения не требуется; этот класс предназначен для общего использования, и даже если это не так, я не могу изменить протокол удаленной стороны.
Хотя я бы предпочел портативное решение, для Windows было бы достаточно конкретного решения, даже если это означает захват родного дескриптора и перечисление событий таким образом. (Это произошло со мной, но WSAEnumNetworkEvents
очищает внутреннюю запись событий, поэтому я подозреваю, что это вызовет проблемы, если реализация boost :: asio зависит от ее чтения.)
В общем случае вам необходимо реализовать некоторый механизм прикладного уровня для обнаружения всех видов разъединений.
На эту тему было много дискуссий о Boost / Asio ML, вот на них.
Вы можете включить опцию сокета TCP_KEEPALIVE, но по-прежнему нужна ожидающая операция чтения, чтобы получить уведомление о сбое чтения.