2017-01-06 8 views
2

Я использую boost::asio для передачи данных в & от клиента к серверу. У меня есть клиентский поток на стороне клиента для чтения данных, полученных в сокете на стороне клиента. Обратите внимание, что я использую boost::asio::read на стороне клиента & boost::asio::write на стороне сервера. Не используется async_read или async_write. Все отлично работает.как отменить операцию `boost :: asio :: read`, пока она ждет

Однако, когда я закрываю приложение, 2 раза в 10 раз приложение не очищается или закрывается должным образом. Он зависает при закрытии. Проблема заключается в следующем:

Моя закрывающая функция вызывается, когда деструкторы вызываются во время закрытия моего приложения. Ниже приведен код Закрыть функции:

socket.cancel(); 
socket.close(); 
boost::system::error_code ec; 
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); 

Проблема заключается в том, что boost::asio::read вызов не возвращает, когда он не получает каких-либо данных & продолжает ждать на него. Это должно быть хорошо, если я могу отменить его. Я пытаюсь сделать socket.cancel на нем, чтобы отменить все операции чтения во время выхода. Однако, похоже, что это не работает. Я читал на некоторых форумах, что socket.cancel отменяет только async_read операций. Это так ? Тогда как можно отменить операцию boost :: asio :: read`, когда моему приложению нужно выйти?

ответ

2

Это характер блокировки IO.

Действительно, socket.cancel() (или даже io_service::stop()) не будет работать при синхронных операциях.

Единственный способ прервать это - использовать тайм-ауты уровня сокета (но Asio не раскрывает это) или использовать асинхронные сигналы (например, нажатие Ctrl-C на терминале отправляет дочерний процесс SIGINT).

Я ранее создал обертку бедного-человек, если вы настаиваете на ведение одиночных операций с тайм-аутом:

+0

Похоже, мне нужно использовать операции асинхронных, чтобы решить эту проблему. Мой C++, который размещает этот код, привык в приложениях на основе пользовательского интерфейса, и это не проблема, потому что я думаю, что «SIGINT» отправляется, чтобы убить все приложение, когда приложение UI будет убито. Это только проблема, когда клиентское приложение является консольным приложением. В любом случае, спасибо за это объяснение –