c++ - 使用 Boost Asio 的快速数据(图像)传输服务器客户端

标签 c++ streaming client-server boost-asio

我是网络编程的新手,对使用 Boost Asio 在客户端和服务器之间连续快速传输数据(图像)的最佳实践有一些疑问。重要的一点,我们不能应用会降低图像质量的压缩。我们使用专用网络(54MBit),除我们之外没有其他流量。我们被推荐使用 Boost Asio,因为它似乎适合我们的需要。然而,由于 Boost 非常强大,它对像我这样没有经验的 (Boost) 开发人员来说是一个挑战。

我们想开发一种尽可能简单的工具,它可以在客户端和服务器之间尽可能快地连续发送图像数据。基本上它是流媒体。我们更愿意使用 TCP,但如果我们可以使用 UDP 获得显着的性能提升,我们不会介意偶尔丢失数据包。

数据是一个无符号字符缓冲区(640x480px = 307200 字节 = 2.34MBit,单色)。

我从 Asio 教程开始,尝试了同步、异步、UDP、TCP 项目。现在,我能够以 ~10fps 发送数据,使用 TCP 每张图像发送 ~0.1ms,使用 UDP 发送~13fps。这太慢了。我预计在 54MBit 网络中发送 2.4MBit 会更快。

今天,我不使用数据的序列化、存档和压缩 (zip) 等。我认为这会改善转移,但我想知道我是否必须满足我的期望和/或我是否必须完全改变我的方法?

数据序列化是使用 Asio 进行数据流传输的方式吗? zip 压缩可能会显着改善传输吗? 是否有替代方法或框架?

TCP 服务器代码示例

// sends data whenever it receives a request by the client
int main(int argc, char* argv[])
{
init_image_buffer();
try
{
    boost::asio::io_service io_service;

    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));

    for (;;)
    {
        tcp::socket socket(io_service);
        acceptor.accept(socket);

        boost::system::error_code ignored_error;
        boost::asio::write(socket, boost::asio::buffer(image_buffer),
            boost::asio::transfer_all(), ignored_error);
    }
}
catch (std::exception& e)
{
    std::cerr << e.what() << std::endl;
}

return 0;
}

TCP 客户端代码示例

我意识到这段代码不是最优的。但我不知道如何使用这种方法保持连接和请求新数据。

int main(int argc, char* argv[])
{
Clock clock;
clock.Initialise();

float avg = 0.0;
float min = 1000000.0;
float max = 0.0;
float time = 0.0;

// sending multiple images
for(int j=0;j<IMAGE_COUNT;j++){

    try
    {
        clock.GetTime();
        if (argc != 2)
        {
            std::cerr << "Usage: client <host>" << std::endl;
            return 1;
        }

        boost::asio::io_service io_service;

        tcp::resolver resolver(io_service);
        tcp::resolver::query query(argv[1], 13);
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::resolver::iterator end;

        tcp::socket socket(io_service);
        boost::system::error_code error = boost::asio::error::host_not_found;

        while (error && endpoint_iterator != end)
        {
            socket.close();
            socket.connect(*endpoint_iterator++, error);
        }
        if (error)
            throw boost::system::system_error(error);

        // we read all received data but do NOT save them into a dedicated image buffer
        for (;;)
        {
            boost::array<unsigned char, 65536> temp_buffer;
            boost::system::error_code error;

            size_t len = socket.read_some(boost::asio::buffer(temp_buffer), error);

            if (error == boost::asio::error::eof)
                break; // Connection closed cleanly by peer.
            else if (error)
                throw boost::system::system_error(error); // Some other error.

        }

        time = clock.GetTime();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    // calculate some time transfer statistics
    avg+=time;
    if(time < min) min = time;
    if(time > max) max = time;

}
std::cout << "avg: " << avg/(float)IMAGE_COUNT << " freq: " << 1.0/(avg/(float)IMAGE_COUNT) << std::endl;
std::cout << "min: " << min << " max: " << max << std::endl;

return 0;
 }

最佳答案

您似乎是在比较帧大小 (2.34MBit) 与网络速度 (54MBit/sec)。如果是这种情况,并且您获得 10 fps,则您的实际速率为 23.4 MBit/秒 –– 这在 54 MBit/秒的连接上还算不错。

无论如何,请告诉我们您最终的设计。

谢谢。

关于c++ - 使用 Boost Asio 的快速数据(图像)传输服务器客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6815039/

相关文章:

windows - 将 rtsp-stream 转换为 http 流

c - 在 UDP 上流式传输

客户端服务器与套接字C的基本通信

java - Android 中同时多个套接字端口连接

c++ - 运算符重载的 friend 关键字

c# - 将一段代码从 C++ 转换为 C#

c++ - 尝试构建非常简单的 gtkmm 应用程序时出现编译器错误 :

c++ - C++ 中结构的存储持续时间和成员初始化

java - 通过 Java 播放实时流音频

javascript - 如何将变量从 Jade 传递到 .JS 文件?