使用Boost::ASIO连续流式传输数据,无需关闭套接字

Continuously streaming data with Boost::ASIO without closing socket

本文关键字:套接字 数据 传输 ASIO Boost 连续 使用      更新时间:2023-10-16

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

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,并大量借用其附带的示例代码),并且可以将航班数据打印到stdout,这没有问题。Boost:ASIO文档展示了一些关于如何构建一个服务器的示例,该服务器可以不断侦听从客户端接收的消息,但没有一个可以发送数据流。

要发送数据流,可以使用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();
}

请注意,为了简单起见,我首先将整个缓冲区放在内存中,假设您可以做到这一点(您说"并且可以将航班数据打印到stdout,没有问题")。因此,您可以将不同的内容写入流(在我的示例中为ostream行)。