我正在编写一个小型的增强型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缓冲区或类似的东西。
答案 0 :(得分:1)
如果出现错误,您不应继续阅读 - &gt;仅在未检测到错误时。 也许你在EOF之后继续读书? 移动调用以读取if中的读取函数。