You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用代码统一使用Boost的socket与serial_port类?

问题描述

我正在开发一个项目,一边学习现代C++和wxWidgets GUI开发,一边打造一款能解决日常问题的应用。这款应用需要支持TCP、UDP、RS232连接,接收纯ASCII数据,还得能同时维持数量不定的多种连接。

最开始我在GitHub上找了TCP客户端和RS232的代码实现了原型,后来根据Stack Overflow的建议改用Boost库,目前用的是boost::asio::ip::tcp::socket和boost::asio::serial_port,UDP还没开始研究。

当处理逻辑需要变更时,我得在多处修改代码,所以想遵循*DRY(Don't Repeat Yourself)*原则优化,但发现这两个类虽然接口相似(同步读写语法完全一致),却没有继承自通用的流类,找不到在代码里统一使用它们的最优方式。

我试过几种方法,想写出统一的连接创建和工作线程运行函数,但都没成功,而且多数方法我也没完全搞懂原理:

  • 模板
  • boost::any返回类型
  • std::variant返回类型
  • void*及union

目前我用来接收、重新缓冲和处理数据的模板函数基本符合预期,代码如下:

template <class Handle>
bool receiveData(Handle& handle){
    std::string line_buffer("");
    boost::system::error_code error;
    boost::asio::streambuf receive_buffer(SERIAL_BUF_SIZE);

    std::size_t bytes_transferred = 
        boost::asio::read(handle, receive_buffer, boost::asio::transfer_at_least(1), error);
    if(error && error !=boost::asio::error::eof){
        std::cout << "\x1b[31;1mError receiving data\x1b[0m" << std::endl;
        return false;
    } else {
        const char* temp_data = boost::asio::buffer_cast<const char*>(receive_buffer.data());
        std::string new_data(temp_data, temp_data+bytes_transferred);
        receive_buffer.consume(bytes_transferred);
        persistent_buffer << new_data;
        persistent_buffer >> std::ws;
        while(std::getline(persistent_buffer, line_buffer, '\r')){
            if(persistent_buffer.eof()) break;
            persistent_buffer >> std::ws;
            if(not line_buffer.empty()){
                updateLiveData(line_buffer);
                line_buffer.clear();
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
        if(persistent_buffer.eof()){
            persistent_buffer.clear();
            persistent_buffer.str({});
            persistent_buffer << line_buffer;
        }
        return true;
    }
}

我希望能实现socket和serial_port的大致互换使用,类似下面代码的效果,但因为经验不足找不到方法。目前我的简单实现能正常运行,但连接创建部分有重复代码:

while(not this->mustDie.load()){
    boost::asio::io_service io_service;
    boost::system::error_code error;

    /*  TCP版本的代码除了这段之外完全一致 */
    boost::asio::serial_port port(io_service);
    port.open("COM"+com_num, error);
    port.set_option(boost::asio::serial_port_base::baud_rate(stoi(baudrate)));
    ////////////////////////////////////////////////////////////

    if(error) {
        std::cout << error.message() << std::endl;
        std::this_thread::sleep_for(CONNECTION_TIMEOUT);
        continue;
        }

    boost::asio::write(port, boost::asio::buffer(QUERY), error);

    while(receiveData(port) and not this->mustDie.load()){
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
}

内容的提问来源于stack exchange,提问作者Allan Menefee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 17:23:10