尝试从 `boost::asio::ip::tcp::iostream` 捕获异常时,“在抛出 'std::__ios_failure' 实例后终止调用”

问题描述

我写了一个简单的阻塞服务器,它等待单个客户端并淹没它。

我使用 boost::asio::ip::tcp::iostream 类与客户端交互,因为我想在将来使用格式化的 I/O。我还想在每次操作后使用异常进行错误处理而不是手动检查标志,所以我以类似于 basic_ios::exceptions 的方式调用 .exceptions()(我假设 Boost 派生自后者,不是吗? ?).

这是结果代码

#include <boost/asio.hpp>
#include <exception>
#include <iostream>
#include <sstream>
#include <utility>

using boost::asio::ip::tcp;

int main() {
    try {
        try {
            boost::asio::io_context io_context;
            tcp::acceptor acceptor(io_context,tcp::endpoint(tcp::v4(),10000));
            std::cout << "Listening at " << acceptor.local_endpoint() << "\n";

            tcp::iostream client(acceptor.accept());
            client.exceptions(std::ios_base::failbit | std::ios_base::badbit |
                              std::ios_base::eofbit);  // (1)
            while (client << "x\n") {
            }
            std::cout << "Completed\n";
        } catch (std::exception &e) {
            std::cout << "Exception: " << e.what() << "\n";
        }
    } catch (...) {
        std::cout << "UnkNown exception\n";
    }
    return 0;
}

不幸的是,看起来一些例外仍然存在。如果我启动服务器,通过 nc localhost 10000 连接,查看 x 片刻,然后 Ctrl+C 客户端,终止它,服务器 std::terminate 带有以下错误消息:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::__ios_failure'
  what():  basic_ios::clear: iostream error

如果我注释掉 (1) 行,则一切正常,当客户端断开连接时,服务器会以 Completed 消息终止。

我在 Windows(g++ (Rev6,Built by MSYS2 project) 10.2.0 和 Boost 1.75.0-3)和 Ubuntu 20.04(g++-10 (Ubuntu 10.2.0-5ubuntu1~20.04) 10.2.0 和 Boost 1.71.0.0ubuntu2)上都试过了。

我做错了什么?

Ubuntu 上的 GDB 会话显示异常是从析构函数内部抛出的,大概是 noexcept,这有点奇怪:

#0  0x00007ffff7e86762 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00007ffff7e7dc63 in std::__throw_ios_failure(char const*) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007ffff7ef0dd2 in std::basic_ios<char,std::char_traits<char> >::clear(std::_Ios_Iostate) ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7f0f28e in std::ostream::sentry::~sentry() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7f0f975 in std::basic_ostream<char,std::char_traits<char> >& std::__ostream_insert<char,std::char_trait
s<char> >(std::basic_ostream<char,std::char_traits<char> >&,char const*,long) ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7f0fd5c in std::basic_ostream<char,std::char_traits<char> >& std::operator<< <std::char_traits<char> >(s
td::basic_ostream<char,char const*) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x000055555555d3a8 in main () at test.cpp:19

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...