c++ - async_read_until 的 Lambda 不初始化长度参数

标签 c++ c++11 boost lambda boost-asio

我正在尝试将 c++11 lambda 与 boost::asio::async_read_until 一起使用,如下所示:

void TCPSession::readData()
{
  auto self(shared_from_this());
  boost::asio::async_read_until(socket_, buffer_, "\r\n",
  [this, self](const boost::system::error_code& ec, std::size_t length)
  {
    log()->debug("received %lu bytes && ec: %d", length, ec); //use boost::log for compile time checking
    std::ostringstream ss;
    ss << &buffer_;
    log()->debug("Received data: %s",ss.str());
    if (!ec){
      log()->debug("We never get here!");
      [... process data ...]
      readData();
    }
  }
 );
}

我观察到的是长度=0。 ec 被适本地设置为 boost EOF 代码。

当我将成员(即 buffer_)转换为字符串时,我也会看到数据。

任何有关初始化长度的建议都会有所帮助。

示例输出:

2014-10-09 14:47:56.968142 [tcp-session] debug: received 0 bytes && ec: asio.misc:2
2014-10-09 14:47:56.974593 [tcp-session] debug: Received data: test7.2.3.5 0.18722307655 2014-10-09 14:47:55.343591
test7.2.3.5 -0.0691607464759 2014-10-09 14:47:55.343837
test7.2.3.5 0.151471040421 2014-10-09 14:47:55.344017
test7.2.3.5 0.172789025585 2014-10-09 14:47:55.344211
test7.2.3.5 0.0409326066787 2014-10-09 14:47:55.344406

最佳答案

尝试

printf("received %lu bytes", length);

// ...
printf("Received data: %s", ss.str().c_str());

或者更好的是,

std::cout << "received " << length << " bytes\n";
// ...
std::cout << "Received data: " << ss.str();

%d 不是 size_t 的正确格式。 (这就是发明 C++ 的原因。几十年前)

注意:如果您启用警告 (-Wall -Wextra -pedantic),您的编译器会告诉您大部分内容

现在, docs say 那个

 // The number of bytes in the streambuf's get
 // area up to and including the delimiter.
 // 0 if an error occurred.

因此,由于 ec 是 EOF,这说明 length 也是 0。

下面的示例打印: Live On Coliru

received 0 bytes, ec: End of file
Received data: hello world
byebye

(假设响应服务器发送“hello world\n”);

完整示例:

#include <boost/asio.hpp>   
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <cstring>
#include <iostream>

struct TCPSession : boost::enable_shared_from_this<TCPSession>
{
    void readData();

    TCPSession(boost::asio::io_service& svc) : socket_(svc) {
        using boost::asio::ip::tcp;
        socket_.connect(tcp::endpoint { {}, 6767 });
    }
    boost::asio::ip::tcp::socket socket_;
    boost::asio::streambuf buffer_;
};

void TCPSession::readData()
{
  auto self(shared_from_this());
  boost::asio::async_read_until(socket_, buffer_, "\r\n",
  [this, self](const boost::system::error_code& ec, std::size_t length)
  {
    std::cout << "received " << length << " bytes, ec: " << ec.message() << "\n";

    std::ostringstream ss;
    ss << &buffer_;
    std::cout << "Received data: " << ss.str();

    if (!ec){
      std::cout << "We never get here!";
      //[... process data ...]
      readData();
    }

    std::cout << "byebye\n";
  }
 );
}

int main()
{
    boost::asio::io_service svc;
    auto sess = boost::make_shared<TCPSession>(svc);

    sess->readData();
    svc.run();
}

关于c++ - async_read_until 的 Lambda 不初始化长度参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26288318/

相关文章:

c++ - 从静态库构建共享库

c++ - 是否可以将成员初始化推迟到构造函数主体?

c++ - std::vector 行为、移动和复制

c++ - 除以 sizeof(void *) 是什么意思?

c++ - 强制执行/定义函数声明

c++ - C++11 中的异步/ future 数量

c++ - 传递给 std::basic_string 的分配器能否具有其虚拟方法

c++ - 创建使用 Boost ASIO 且不公开它的静态库

c++ - 某些代码未从代码覆盖率中删除

c++ - 没有 Boost 的现代 C++ 中的 bimap 实现