Проблема с ASIO io_service для запуска несколько раз

По моему вопросу. Я — клиент, и моя цель — писать на сервере только тогда, когда это требуется, а не каждый раз.

У меня есть один одноэлементный класс (класс вызывающего абонента), в котором я вызываю свою клиентскую программу (клиент), чтобы написать любое сообщение на сервере, и
затем вызывая boost :: asio :: io_service :: запустить через один поток.
Моя клиентская программа (Client) также является синглтон-классом.

Моя программа работает нормально, если сервер уже запущен. Потому что клиент будет подключаться к серверу в первую очередь. Но если сервер перезагружается или не работает, сначала я должен проверить, работает ли сервер, или нет, прежде чем писать сообщение.

Чтобы каждый раз проверять, доступен ли сервер или нет, я должен вызвать Caller :: run () и запустить io_service.

Без запуска io_service я не могу проверить, работает ли сервер или нет, так как я использую всю синхронизацию в моей программе.
Все в асинхронном режиме (асинхронное соединение, синхронная запись)

Моя проблема в том, что иногда моя программа переходит в состояние + D1 (непрерывный сон), а затем я не могу закрыть свою программу.
Это связано с io_service ()?

Как я могу проверить, включен сервер или нет без запуска io_service?

 class Caller
{
public:

static Caller* getInstance()
{
static Caller Caller;
return &Caller;
}

void run()
{
pWork.reset( new boost::asio::io_service::work(io_service) );

////////////calling client program////////////////
Client::getInstance(io_service)->start();

thread = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
}

boost::asio::io_service io_service;
boost::shared_ptr<boost::asio::io_service::work> pWork;

boost::thread thread;

private:
Caller()
{
}
~Caller()
{
pWork.reset();
thread.join();
}
};///////////my client program (Singleton Class)//////////////////
//////message write function///////////

void Client::sendResponse(std::string& messag)
{
boost::system::error_code error;
boost::asio::ip::tcp::endpoint endpoint = socket().remote_endpoint(error);

if ( error )
{
DEBUG_2("could not write: ",boost::system::system_error(error).what());
this->stop(); /////this will close the socket////
Caller::getInstance()->run();
//////it will call the caller program to call the  connect function of client program /////
}
else
boost::asio::async_write(
_socket,
boost::asio::buffer( message.c_str(), message.size()),
_strand.wrap(
boost::bind(
&Client::writeHandler,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
}Client *Client::getInstance(boost::asio::io_service& io_service)
{
if (!Client)
{
Client = new Client(io_service);
}
return Client;
}

Можно ли спроектировать таким образом, что я просто пишу на сервер, и нет необходимости запускать io_service снова и снова.
или мне нужно вызвать io_service :: reset ()
Я правильно использую работу?

Как я могу остановить или прервать это изящно?
вызывая io_servie :: stop или присоединяясь к этой теме?

1

Решение

Типичная методология определения достоверности соединения заключается в выполнении async_read() после успешного подключения когда async_read() обратный вызов указывает на boost::asio::error::eof ошибка, ваше приложение должно реагировать соответствующим образом:

  1. переподключиться, возможно с задержкой по таймауту
  2. прекратить грациозно
  3. выкинуть

Похоже, вам нужен вариант № 1. Когда написано правильно, ваше приложение должно только вызвать io_service::run() однажды цикл событий будет постоянно иметь работу.


Если вы не хотите читать из сокета, чтобы обнаружить закрытие, создайте экземпляр work объект и держать его в области действия на время вашей программы. Это обеспечит io_service всегда есть над чем работать Когда ваш async_write Обработчик завершения вызывается с ошибкой, реагируйте так, как необходимо для вашего приложения, как предлагалось ранее.

1

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector