TCP数据重新计时超时对我不起作用

时间:2012-02-16 13:05:17

标签: c++ boost tcp boost-asio

我有一个提升异步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 个答案:

答案 0 :(得分:1)

设置SO_RCVTIMEO会导致对read的其他阻塞调用在等待指定时间后没有数据返回,因为非阻塞套接字会立即执行。

所以,问题是,当read返回EWOULDBLOCK错误时,你或Boost做了什么?你需要展示你是如何阅读的;如果Boost在事件循环中处理它(基于selectpoll),它可能只是等待一些数据可用。

如果是这种情况,更好的方法是使用事件循环注册一个计时器回调来每秒或多次触发,并检查在前一秒内是否收到了一些数据。套接字选项对你没有帮助。