【问题标题】:boost read_some function lost databoost read_some 函数丢失数据
【发布时间】:2013-07-15 11:42:13
【问题描述】:

我正在实现一个带有 boost asio 库的 tcp 服务器。 在服务器中,我使用 asio::async_read_some 获取数据,并使用 asio::write 写入数据。服务器代码是这样的。

std::array<char, kBufferSize> buffer_;
std::string ProcessMessage(const std::string& s) {
   if (s == "msg1") return "resp1";
   if (s == "msg2") return "resp2";
   return "";
}
void HandleRead(const boost::system::error_code& ec, size_t size) {
  std::string message(buffer_.data(), size);
  std::string resp = ProcessMessage(message);
  if (!resp.empty()) {
    asio::write(socket, boost::asio::buffer(message), WriteCallback);
  }
  socket.async_read_some(boost::asio::buffer(buffer_));
}

然后我写了一个客户端来测试服务端,代码是这样的

void MessageCallback(const boost::system::error_code& ec, size_t size) {
   std::cout << string(buffer_.data(), size) << std::endl;
}
//Init socket
asio::write(socket, boost::asio::buffer("msg1"));
socket.read_some(boost::asio::buffer(buffer_), MessageCallback);
// Or async_read
//socket.async_read_some(boost::asio::buffer(buffer_), MessageCallback);
asio::write(socket, boost::asio::buffer("msg1"));
socket.read_some(boost::asio::buffer(buffer_), MessageCallback);
// Or async_read
//socket.async_read_some(boost::asio::buffer(buffer_), MessageCallback);

如果我运行客户端,代码将在第二个 read_some 等待,输出为:resp1。

如果我删除第一个 read_some,输出是resp1resp2,这意味着服务器做对了。

似乎第一个 read_some EAT 第二个响应,但不给 MessageCallback 函数响应。

我已经阅读了What is a message boundary? 的问题,我认为如果这个问题是“消息边界”问题,第二个 read_some 应该打印一些东西,因为第一个 read_some 只从 tcp 套接字获取部分流。

我该如何解决这个问题?

更新: 我尝试将客户端缓冲区的大小更改为 4,输出将是:

resp
resp

看来 read_some 函数会比从套接字读取更多的功能,我将阅读 boost 代码来确定是否属实。

【问题讨论】:

  • @chrisaycock 我已经阅读了您提到的问题并更新了问题,我认为如果这是一个消息边界问题,第一个 read_some 将获得整个“resp1resp2”或第二个 read_some 应该获得插座上的东西,对吗?
  • 什么是asio::read_some?我在 Asio 文档中没有看到这样的免费功能。您能否更正您的问题,以便更准确地反映您在做什么?
  • async_read_some() 是成员函数,而不是 free function。这个问题中的代码没有意义,因为asio::async_read_some() 不会编译。
  • @sam-miller,对不起,我的意思是使用 socket.async_read_some 函数,并且在我提问时出错,我已经更新了问题。

标签: c++ boost tcp boost-asio


【解决方案1】:

async_read_some() 成员函数很可能没有按照您的意愿行事,请特别注意文档的备注部分

读取操作可能不会读取所有请求的字节数。 如果您需要确保 在异步操作之前读取请求的数据量 完成。

请注意,async_read() 免费功能确实提供了您正在寻找的保证

这个操作是在零次或多次调用 流的async_read_some 函数,被称为组合 手术。程序必须确保流不执行其他 读操作(如async_read,流的async_read_some 函数或任何其他执行读取的组合操作)直到 此操作完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多