правильно прекратить boost :: asio :: ip :: tcp :: accept (Linux)

Интересно, как реализовать синхронный сокет accept с boost, который можно прекратить.

Чтобы продемонстрировать свою проблему, я немного изменил Пример синхронного TCP эхо.

Примечание: предоставленный код, кажется, работает на платформах Windows, но у меня проблемы на компьютере с Linux.

Допустим, сервер получает сообщение о выходе и теперь хочет завершить бесконечный цикл, который принимает новые соединения.
В большинстве уроков и т. Д. Рекомендуется в этом случае запускать acceptor-> close (). Но, как
эта почта государства, результаты могут быть неопределенными, если close() вызывается из другого потока.

Если ты так сделаешь, accept() на этот раз не завершится, но когда другой клиент пытается подключиться, он возвращает ошибку (в Linux!)

Итак, мой вопрос еще раз: как мне правильно завершить работу сервера, который основан на boost::asio который непрерывно синхронно принимает соединения?

Вот код:

#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

using boost::asio::ip::tcp;

void session(boost::shared_ptr<tcp::socket> sock, tcp::acceptor *acceptor )
{
try {
for (;;) {

char data[ 1024 ];

boost::system::error_code error;
size_t length = sock->read_some(boost::asio::buffer(data), error);
if (error == boost::asio::error::eof) { break; }
else if (error) { throw boost::system::system_error(error); }

if( std::string("quit") == data ) {    // TRY TO CANCEL THE ACCEPT
acceptor->close();
break;
}
boost::asio::write(*sock, boost::asio::buffer(data, length));
}
}
catch (std::exception& e) { std::cerr << "exception in thread: " << e.what() << "\n"; }
}

void server(boost::asio::io_service& io_service, short port)
{
tcp::acceptor a( io_service, tcp::endpoint(tcp::v4(), port) );
for (;;) {
boost::shared_ptr<tcp::socket> sock(new tcp::socket(io_service));
boost::system::error_code error;
a.accept( *sock, error );

if( !error ) {
boost::thread t( boost::bind( session, sock, &a ) );
}
else {
std::cout << "acceptor canceled "<< error << std::endl;
break;
}
}
}

int main(int argc, char* argv[])
{
try{
// ..check args here...

boost::asio::io_service io_service;
server(io_service, std::atoi(argv[1]));
}
catch (std::exception& e) {std::cerr << "Exception: " << e.what() << "\n";}

return 0;
}

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]