C ++ Boost ASIO: как читать / писать с таймаутом? - PullRequest
22 голосов
/ 29 декабря 2010

Из прочтения других записей переполнения стека и документации boost::asio я подтвердил, что нет синхронных вызовов ASIO для чтения / записи, которые также предоставляют простой в использовании тайм-аут в качестве параметра для вызова.

Я нахожусь в процессе преобразования приложения сокетов Linux старой школы с вызовами select (2), использующими тайм-ауты, и мне нужно сделать более или менее то же самое.

Так что же такоелучший способ сделать это в boost::asio?Глядя на документацию asio, можно найти много запутанных примеров различных вещей, связанных с таймерами, но я совершенно сбит с толку.

Я хотел бы увидеть простой пример этого: Чтение из сокета, но ожидание не более X секунд, после чего функция либо возвращается с пустым значением, либо возвращается с тем, что ей удалось прочитать из сокета, до истечения времени ожидания.

Ответы [ 2 ]

6 голосов
/ 07 июля 2013

Я использовал несколько asio docs , чтобы произвести это:

class TimeoutAdjust
{
public:
  TimeoutAdjust(unsigned int dwTimeout) : m_dwTimeout(dwTimeout) {};

  template<class Protocol>
  int level(const Protocol& p) const {return SOL_SOCKET;}

  template<class Protocol>
  int name(const Protocol& p) const {return SO_SNDTIMEO;}

  template<class Protocol>
  const void* data(const Protocol& p) const {return &m_dwTimeout;}

  template<class Protocol>
  size_t size(const Protocol& p) const {return sizeof(m_dwTimeout);}
private:
  unsigned int m_dwTimeout;
};

Использование:

TimeoutAdjust adjust(5000);
sSocket.set_option(adjust);

Я отладил его, и он, кажется, делает то, что должен.

6 голосов
/ 29 декабря 2010

Это было поднято в списках рассылки asio, есть тикет , запрашивающий эту функцию.Подводя итог, предлагается использовать асинхронные методы, если вам нужны таймауты и возможность отмены.


Если вы не можете конвертировать в асинхронные методы, вы можете попробовать опции сокетов SO_RCVTIMEO и SO_SNDTIMEO.Их можно установить с помощью setsockopt, дескриптор можно получить с помощью метода boost :: asio :: ip :: tcp :: socket :: native .На справочной странице man 7 socket написано

SO_RCVTIMEO и SO_SNDTIMEO Укажите тайм-ауты получения или отправки до сообщения об ошибке.Аргумент является структурой timeval.Если функциональные блоки ввода или вывода на этот период времени и данные были отправлены или получены, возвращаемое значение этой функции будет количеством переданных данных;если данные не были переданы и тайм-аут достигнут, то возвращается -1 с errno, установленным в EAGAIN или EWOULDBLOCK, как если бы сокет был указан как неблокирующий.Если тайм-аут установлен на ноль (по умолчанию), то операция никогда не будет тайм-аут.Тайм-ауты действуют только для системных вызовов, которые выполняют сокет-ввод / вывод (например, read (2), recvmsg (2), send (2), sendmsg (2));таймауты не влияют на select (2), poll (2), epoll_wait (2) и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...