从客户端收到所有数据后提升asio streambuf垃圾

时间:2014-02-13 13:53:14

标签: c++ boost-asio

我正在编写一个小型的增强型asio tcp服务器和发送和接收纯文本的客户端。通信或多或少是请求响应。在测试期间,我想我只是用数据向服务器发送垃圾邮件,向它发送100,000个请求。

从客户端发送到服务器的消息:

  

\ n = BEGIN 1,测试\ n
  你好世界:1
  \ N = END \ n

在上面的消息中,计数器从0到99.999(在上面的例子中它是1,如“BEGIN 1”和“Hello World:1”)。

如上所述,这样可以正常工作,服务器收到所有100.000条消息,但是一旦传输了所有消息,尽管没有从客户端发送数据,但最多可以调用多次读取处理程序。

从streambuf对象中读取数据会产生旧消息的残余,如:

  

IN 61868,测试\ n
  你好世界:61868
  \ N = END \ n

  

= END \ n
  = END \ n

奇怪的是,它似乎只在消息数量超过一定数量时发生,但它不一致,导致我相信某些溢出或UB在某处发生,因此我显然已经做了一些事情错了,但我似乎无法弄清楚是什么。阅读代码是:

 typedef boost::shared_ptr<boost::asio::streambuf>       asio_streambuf_ptr;
 typedef boost::shared_ptr<boost::asio::ip::tcp::socket> asio_socket_ptr;

 ...

 void on_read(const asio_socket_ptr& s, const asio_streambuf_ptr& b,
     const boost_error_code& e, size_t length) {

   if ( !e ) {

       std::string temp(boost::asio::buffer_cast<const char*>(b->data()), length);
       //process temp

       b->consume(length);
   } else {
       //Handle the error - or close the socket if disconnected
       handle_error(s, e);
   }

   read(s, b);
 }

 void read(const asio_socket_ptr& s, const asio_streambuf_ptr& buf) {

     if (s->is_open()) {
       boost::asio::async_read_until(*s, *buf, "\n=END\n",
           boost::bind(on_read, s, buf, boost::asio::placeholders::error,
             boost::asio::placeholders::bytes_transferred));
     }
 }

我的第一个on_read函数实现使用std :: istream和std :: getline来逐行读取每个消息,但问题也出现在那里,因为gdb中的流很难检查我重写了它让它更容易调查。

现在我必须强调一点,我是boost-asio的新手,这是我第一次尝试使用boost的那部分做一些有用的东西,因此我接受我很可能会误解几个概念。异步io系统。

所以我的问题:有没有人经历过这个问题,或者对我做错了什么有任何建议?

我已经制作了一个SSCCE,但因为它涉及相当数量的代码作为服务器和客户端,我想我会等到这里发布它,直到有人要求它。

更新 问题似乎是客户端写邮件的速度比服务器读取邮件的速度快。限制客户端稍微修复了问题。注意:更改内部缓冲区大小没有帮助,所以似乎客户端泛滥了一些os-network缓冲区或类似的东西。

1 个答案:

答案 0 :(得分:1)

如果出现错误,您不应继续阅读 - &gt;仅在未检测到错误时。 也许你在EOF之后继续读书? 移动调用以读取if中的读取函数。