【问题标题】:Continuously streaming data with Boost::ASIO without closing socket使用 Boost::ASIO 连续传输数据而不关闭套接字
【发布时间】:2014-10-31 21:14:10
【问题描述】:

我正在尝试构建一个应用程序:

a) 在内部运行 FDM(飞行动力学模型),并管理飞行数据

b) 接受 TCP 套接字上的连接

c) 通过所述套接字提供飞行数据。

我目前已经设法使用 Boos::ASIO 网站上的示例/教程在我的本地套接字上通过 TCP 发送一个简单的字符串:http://www.boost.org/doc/libs/1_56_0_b1/doc/html/boost_asio/tutorial.html

我的麻烦只是写完单个字符串后连接关闭,不知道如何保持连接打开并不断发送数据,直到模拟完成(或从监听发送停止信号应用)。

我也有 FDM 工作(目前使用 JSBSim,并从他们包含的示例代码中大量借用),并且可以将飞行数据打印到标准输出没有问题。 Boost:ASIO 文档展示了一些示例,说明如何构建一个服务器,该服务器不断侦听从客户端接收到的消息,但没有一个将数据流发送出去。

【问题讨论】:

    标签: c++ sockets boost tcp


    【解决方案1】:

    要发送数据流,您可以使用boost::asio::streambuf 的免费函数。

    这是一个简单的演示,它向每个客户端发送自己的源代码:

    #include <boost/asio.hpp>
    #include <boost/make_shared.hpp>
    #include <boost/function.hpp>
    #include <boost/asio/posix/stream_descriptor.hpp>
    #include <fstream>
    #include <iostream>
    
    namespace io = boost::asio;
    namespace ip = io::ip;
    using boost::system::error_code;
    using boost::make_shared;
    using ip::tcp;
    
    void start_accept(io::io_service& svc, tcp::acceptor& acc) {
        // per-connection lifetimes:
        auto sock = make_shared<tcp::socket>(svc);
    
        acc.async_accept(*sock, [sock,&svc,&acc](error_code ec) {
            if (!ec)
            {
                std::cout << "connection from " << sock->remote_endpoint() << "\n";
    
                // copy source file to buffer data
                auto data = make_shared<io::streambuf>();
                std::ostream(data.get()) << std::ifstream("main.cpp").rdbuf();
    
                // now write the whole story
                io::async_write(*sock, *data, [sock,data/*keep alive*/](error_code ec, size_t transferred){});
    
                // accept new connections too
                start_accept(svc, acc);
            }
        });
    }
    
    int main()
    {
        io::io_service svc;
        tcp::acceptor acc(svc, tcp::endpoint(ip::address(), 6767));
    
        start_accept(svc, acc);
    
        svc.run();
    }
    

    请注意,为简单起见,我首先将完整的缓冲区放入内存中,假设您可以这样做(您说过 “并且可以将飞行数据打印到标准输出没有问题”)。因此,您可以将不同的内容写入流(在我的示例中为 ostream 行)。

    【讨论】:

    • 这非常有帮助,谢谢!我还发现,只要不是每次在循环中都重新创建接受器和套接字(这是 boost 示例所显示的),我就可以保持连接处于活动状态。另一个问题是:对于这样的异步写入,连接是否会在整个程序中保持活动状态,即使您不经常写入/保持缓冲区满?
    • 套接字的生命周期决定了连接的生命周期(除非远端关闭它,或者close()/shutdown()被显式调用)
    猜你喜欢
    • 2016-10-27
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2012-01-16
    • 2016-09-02
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    相关资源
    最近更新 更多