- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在编写一个发送和接收纯文本的小型 boost asio tcp 服务器和客户端。通信或多或少是请求响应。在测试期间,我想我只是向服务器发送垃圾数据,向它发送 100.000 个请求。
客户端发送给服务器的消息:
\n=BEGIN 1,test\n
Hello World: 1
\n=END\n
在上面的消息中,计数器从 0 变为 99.999(在上面的示例中,它是 1,如“BEGIN 1”和“Hello World: 1”)。
如前所述,这工作正常,服务器收到了所有 100.000 条消息,但是一旦所有消息都被传输,读取处理程序将被调用多次,尽管没有从客户端发送数据。
从 streambuf 对象中读取数据会产生旧消息的残余,如:
IN 61868,test\n
Hello World: 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 的那部分做一些有用的东西,因此我承认我很可能误解了 boost-asio 的几个概念异步io系统。
所以我的问题是:有没有人以前经历过这种情况或对我做错了什么有任何建议?
我已经制作了一个 SSCCE,但由于它涉及相当多的代码作为服务器和客户端,我想我会等到有人请求它时再将它发布到这里。
更新:问题似乎是客户端写入消息的速度比服务器读取消息的速度快。节流客户端稍微解决了这个问题。注意:更改内部缓冲区大小没有帮助,因此客户端似乎淹没了一些操作系统网络缓冲区或类似的东西。
最佳答案
如果出现错误,您不应该继续阅读 -> 只有在未检测到错误时才继续阅读。也许你在 EOF 之后继续阅读?将对 read 的调用移至 if 中的 read 函数中。
关于c++ - 从客户端收到所有数据后提升 asio streambuf 垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21756194/
我试图理解 boost::asio::streambuf::consume() 和 boost::asio::streambuf::commit() 调用.在文档中,我们有示例, boost::asi
我搜索了其他帖子,但没有找到任何相关内容。现在,我有一个由 header 和正文组成的协议(protocol)。协议(protocol)是这样的:Z24,91009802,123456789ABCDE
为了接收带有自定义 header 以太网帧的原始协议(protocol),我正在使用 streambuf 缓冲区从以太网中读取字节。大部分有效载荷被成功复制,但我需要检查缓冲区中帧头的特定字节,以便我
我似乎无法很好地解释 consumer() 和 commit() 的真正含义,实际上我根本不了解 streambuf。 我的理解是streambuf只是一个字符数组。但是为什么在文档中, basic_
我正在定义一个自定义 std::streambuf 类以用于文件 I/O。在这个类中,我正在重载函数 open、close、is_open、xsgetn、xsputn、溢出、下溢 和 uflow。然后
我正在使用streambuf作为串口通信的存储 io_service io; serial_port sp(io); sp.open("COM4"); sp.set_option( serial_po
protected 虚拟成员函数 streambuf::xsgetn 使 I/O 流实现者能够定义一个函数,该函数从输入流中提取 n 个字符并将它们存储在缓冲区中. 通常,对于像fstream 这样的
我使用的是 simple file-slurp我决定添加一些错误检查。我很惊讶一个空文件会出错。这也不会发生在每个空序列上,“”工作正常。我还验证了 rdbuf() 正在返回一个非空指针。 #incl
我正在研究 boost::asio::streambuf 并发现我可以使用它发送/获取一个结构,但是当我发送一个结构时我无法获取它我已经发送了。文档说应该使用 commit() 和 consume()
我正在尝试将读取 gz 文件的代码打包成一个函数,源代码取自 https://techoverflow.net/2013/11/03/c-iterating-lines-in-a-gz-file-us
我有一个 Visual Studio 2008 C++ 项目,我在其中尝试将来自多个类的数据序列化为自定义 std::streambuf 实现。 数据类及其序列化: struct Header { /
我将 C++ streambuf 类用于编译器项目,需要一种方便的方法来获取流中的当前位置。 有两个成员函数,streambuf::pubseekpos 和一个streambuf::pubseekof
我对 boost asio::streambuf 类中的输入序列和输出序列感到困惑。 根据文档中的代码示例(用于发送数据),表示输入序列的缓冲区似乎用于写入套接字,而表示输出序列的缓冲区用于读取。 例
几天前,我决定编写一个使用mmap 和预读的streambuf 子类会很有趣。我查看了我的 STL (SGI) 如何实现 filebuf 并意识到 basic_filebuf 包含一个 FILE*。所
我正在尝试找到一种方法来获取读取或写入流的字符数,即使出现错误并且读/写结束很短也是可靠的。 我正在做这样的事情: return stream.rdbuf()->sputn(buffer, buffe
流的 streambuf 是否有可能在其原始流被销毁后仍然存在? streambuf* f() { ifstream my_stream; // ... return my_s
显然 boost::asio::async_read 不喜欢字符串,因为 boost::asio::buffer 的唯一重载允许我创建 const_buffer,所以我一直坚持将所有内容读入 stre
我不太明白使用 streambuf 相对于常规数组的优势。让我解释一下我的问题。我有一个使用 Rijndael 128 ECB + 一些简单密码加密的网络连接,用于加密小于 16 字节的剩余数据。数据
出于教育目的,我想创建一个 ostream 和流缓冲区来做: 在执行 << myVar; 时修复字节序 存储在双端队列容器中,而不是使用 std:cout 或写入文件 记录额外的数据,例如我做了多少次
显然 boost::asio::async_read 不喜欢字符串,因为 boost::asio::buffer 的唯一重载允许我创建 const_buffers,所以我坚持将所有内容读入流缓冲区。
我是一名优秀的程序员,十分优秀!