提升read_some函数丢失数据

时间:2013-07-17 04:14:57

标签: c++ boost tcp boost-asio

我正在使用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套接字中获取流的一部分。 / p>

我该如何解决这个问题?

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

resp
resp

看起来read_some函数会比从套接字读取更多一点,我会读取增强代码来找出是真的。

1 个答案:

答案 0 :(得分:1)

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

  

读取操作可能无法读取所有请求的字节数。   如果您需要确保使用async_read功能,请考虑使用   在异步操作之前读取请求的数据量   完成。

请注意,async_read()免费功能确实可以保证您正在寻找

  

此操作是根据对零的或多个调用实现的   stream的async_read_some函数,被称为组合   操作。程序必须确保流不执行任何其他操作   读取操作(例如async_read,流的async_read_some   函数,或执行读取的任何其他组合操作,直到   此操作完成。