Я написал схему связи tcp с использованием boost asio, и она работает вполне нормально, если я использую отдельный поток для io_service::run()
.Тем не менее, коммуникатор также должен использоваться как часть параллельной MPI-программы (пожалуйста, не задавайте вопросов), где разветвление и многопоточность не являются хорошей идеей и могут быть недопустимы.
Для этого коммуникатор имеетфункция work()
, которая вызывает io_service::run_one
.Теперь, если я напрямую использую async_read
, будет блокироваться вызов run_one
до тех пор, пока что-то не будет прочитано или не произойдет ошибка.Итак, я написал функцию check_available
, показанную ниже, которая сначала проверяет, есть ли что-то в сокете, прежде чем вызывать async_read
в моей функции read_message_header
.
. Это также работает гладко, пока узел не закроет соединение.К сожалению, socket::available(error)
, похоже, не помечает это как ошибку eof, как в случае async_read
, и возвращает 0 как количество доступных байтов, так что read_message_header
никогда не вызывается, что затем обнаружитВФ.Также проверка socket::is_open()
не сработала для этой цели, потому что закрыты только сокеты однорангового узла, а не получающий сокет в этом случае.
void TCPConnection::check_availble() {
if(! socket_.is_open()) {
handle_read_error(boost::asio::error::eof);
}
boost::system::error_code error;
size_t nbytes=socket_.available(error); // does not detect the eof
if(error)
handle_read_error(error);
if(nbytes>0)
read_message_header();
else
socket_.get_io_service().post(
boost::bind(
&TCPConnection::check_availble,
shared_from_this()
)
);
}
Есть ли способ обнаружить eof без каких-либо блокирующих вызовов?