Тайм-аут записи данных TCP не работает для меня - PullRequest
1 голос
/ 16 февраля 2012

У меня есть улучшенный асинхронный tcp-клиент, которому нужно постоянно получать данные с сервера.Я хочу поставить там тайм-аут, что, если не получить данные в течение n секунд, отключиться от сервера и попытаться подключиться.и я использую vc ++.

  void tcpclient::Connect(){
    .....
    socket_.async_connect(*iterator,boost::bind(&tcpclient::AfterConnection,shared_from_this(),boost::asio::placeholders::error));
  }

  void tcpclient::AfterConnection(const boost::system::error_code& error){
        if (!error)
        {
           SetTimeout();
        }
  }

  void tcpclient::SetTimeout(int sec = 1)
  {

    SOCKET native_sock = socket_.native();
    int result = SOCKET_ERROR;
    if (INVALID_SOCKET != native_sock)
    {
      struct timeval tv;
      tv.tv_sec = sec;
      tv.tv_usec = 0;
      result = setsockopt(native_sock, SOL_SOCKET, SO_RCVTIMEO,(char *)&tv,sizeof(struct timeval));
      i = GetLastError();

    }

  } 

, и я читаю как удар:

        socket_.async_receive(boost::asio::buffer(buffer, 1024),
            boost::bind(&tcpClient::handleReceive,
            shared_from_this(),
            boost::asio::placeholders::error,
            buffer,
            boost::asio::placeholders::bytes_transferred)
            );

, но когда я пытаюсь смоделировать случай, который не обеспечивает соединение данных, остается установленным:

$ netstat -ao

TCP 192.168.0.6:62836 192.168.0.5:telnet ESTABLISHED 2840

В чем проблема, почему это произошло?

1 Ответ

1 голос
/ 16 февраля 2012

Установка SO_RCVTIMEO приводит к тому, что вызовы, блокирующие в противном случае read, возвращаются без данных после ожидания в течение указанного времени, поскольку неблокирующий сокет должен был бы это сделать сразу.Что вы или Boost делаете, когда read возвращает ошибку EWOULDBLOCK?Вы должны показать, как вы делаете чтение;если Boost обрабатывает его в цикле событий (на основе select или poll), он, вероятно, просто ждет, когда некоторые данные станут доступными.

Если это так, лучшим подходом является регистрация таймера.обратный вызов с циклом событий, который запускается каждую секунду или как часто, и проверяет, получили ли вы какие-либо данные в течение предыдущей секунды.Опции сокетов не помогут вам в этом.

...