2009-05-04 3 views
5

Что является самым простым способом проверить, был ли сокет закрыт на удаленной стороне соединения? socket::is_open() возвращает true, даже если он закрыт на удаленной стороне (я использую boost::asio::ip::tcp::socket).Как проверить, закрыт ли сокет в Boost.Asio?

Я мог бы попытаться прочитать из потока и посмотреть, удастся ли ему это сделать, но мне придется изменить логику моей программы, чтобы она работала таким образом (я не хочу, чтобы данные извлекались из потока на точка проверки).

+0

Зачем вам нужно знать, закрыто ли удаленное соединение? – outis

+0

Кроме того, вы используете протокол приложения вашего собственного дизайна или стандартный протокол? – outis

+0

Я пишу базовую программу чата, и мне нужно уведомить пользователя о том, что другой человек закрыл приложение. У меня есть собственный протокол, и я уже добавил сообщение «Quit». Единственный недостаток заключается в том, что он не отправляется, если приложение убито/сбой/etc. – Hali

ответ

4

Если соединение было чисто закрыто сверстником, вы должны получить EOF во время чтения. В противном случае я обычно пингую, чтобы выяснить, действительно ли соединение действительно живое.

+1

... и мне нужно прочитать, чтобы получить EOF. Думаю, в этом нет никакого способа. Спасибо! – Hali

7

Доступна ли функция подзабытия? Большинство реализаций сокетов имеют возможность читать данные, не удаляя их из очереди, поэтому вы можете прочитать их позже. Это, похоже, удовлетворит ваши требования.

После быстрого обзора документов asio я не смог найти то, что ожидал, но это не значит, что его нет.

Я предлагаю this для начала.

+0

Да, ты прав. Вы можете передать флаг методу «получать», который говорит, что он не удаляет данные. Я использовал метод read_some, который не имеет этого аргумента. Спасибо, что указали! – Hali

+0

Предположим, что вы настроили сокет и ответ, тогда вы можете настроить поток, например. std :: istream myhttpstream (& presponse); а затем вы можете использовать функцию std :: istream :: peek(). – 2012-01-29 22:56:27

+0

Я делаю это: received = socket(). Получать (boost :: asio :: buffer (buf), tcp :: socket :: message_peek); –

1

Я думаю, что, как только вы откроете сокет, вы должны сразу начать читать его и никогда не прекращать это делать. Таким образом, вы можете заставить ваш сервер или клиент поддерживать как синхронные, так и асинхронные протоколы. В тот момент, когда клиент закрывает соединение, момент, когда прочитанное скажет вам это.

0

Использование error_code позволяет проверить состояние подключения клиента или нет. Если соединение выполнено успешно, error_code error.value() вернет 0, else вернет другое значение. Вы также можете проверить сообщение() с error_code.

7

Просто зарегистрируйтесь для boost::asio::error::eof Ошибка в вашем async_receive обработчике. Это означает, что соединение было закрыто. Это единственный правильный способ сделать это.

Смежные вопросы