TCP 数据记录超时对我不起作用

TCP data rec timeout don't work for me

本文关键字:不起作用 超时 数据 记录 TCP      更新时间:2023-10-16

我有一个boost异步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

发生这种事的原因是什么?

设置SO_RCVTIMEO会导致对read的阻塞调用在等待指定时间后返回,而没有数据,就像非阻塞套接字会立即返回一样。

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

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