繁体   English   中英

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

[英]boost asio streambuf garbage after all data received from client

我正在写一个小的boost asio tcp服务器和客户端,用于发送和接收纯文本。 通讯或多或少是请求响应。 在测试期间,我发现我只是向服务器发送数据垃圾邮件,向其发送100.000个请求。

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

\\ n =开始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缓冲区或达到此目的的东西。

如果出现错误,则不应继续阅读->仅在未检测到错误的情况下。 也许您在EOF之后继续阅读? 移动调用以读取if中的函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM