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

TCP套接字传输桌面截图一段时间后速率下降的原因排查

问题分析:TCP传输桌面截图速率下降原因

问题描述

我尝试通过TCP套接字向服务器发送桌面截图,初始时一切正常,可达约30FPS,但一段时间后传输速率变慢。我曾怀疑是内存泄漏,已在循环中删除数据并关闭文件,但问题仍存在。以下是服务器端和客户端代码,请问速率下降的具体原因是什么?

服务器端代码

while(!is_client_dead){

    char file_size[1024];

    recv(m_video_socket,file_size,1024,0);

    char *data = new char[std::atoi(file_size)];

    recv(m_video_socket,data,std::atoi(file_size),0);
    
    std::fstream file("screenshot.png",std::ios::out | std::ios::binary | std::ios::trunc);

    for(int x{0};x<std::atoi(file_size);x++)
        file << data[x];

    delete [] data;

    file.close();

    cv::Mat image = cv::imread("screenshot.png");

    cv::resize(image,image,cv::Size(image.cols/2,image.rows/2));

    cv::imshow(m_name + "'s screen",image);

    cv::waitKey(1);

} 

客户端代码

while(!is_server_dead){

    cv::Mat image;

    capture_screen(image);

    cv::imwrite("screenshot.png",image);

    std::size_t size = std::filesystem::file_size("screenshot.png");
    
    send(m_client_video,std::to_string(size).c_str(),1024,0);

    std::ostringstream file_buffer; 
    
    std::fstream file("screenshot.png",std::ios::in | std::ios::binary);

    file_buffer << file.rdbuf();

    std::string file_data = file_buffer.str();

    send(m_client_video,file_data.c_str(),size,0);

    file.close();

}

速率下降的核心原因

  • 磁盘IO瓶颈:客户端每次将截图写入本地文件再读取发送,服务器端接收数据后也写入本地文件再读取显示。频繁的磁盘读写会随着时间积累导致IO队列阻塞,缓存耗尽后物理IO延迟大幅增加,直接拖慢整体传输速率。
  • TCP传输未处理完整读写:recv和send不保证一次性完成指定长度的读写。比如服务器端可能只接收到部分数据就继续后续操作,导致文件写入不完整、imread读取异常,长期运行积累错误状态引发卡顿;客户端send也可能未发完数据,导致服务器端等待剩余数据,拖慢传输节奏。
  • 重复字符串转数字的隐患:服务器端多次调用std::atoi(file_size),若file_size存在非法字符或转换错误,会导致内存分配、循环写入的长度出错,引发内存越界或数据不完整,长期运行积累问题导致速率下降。
  • 客户端数据复制开销:用std::ostringstream读取文件到std::string会额外复制数据,增加内存开销和处理时间,长期运行积累内存碎片,影响整体性能。

优化建议

  • 跳过磁盘IO:客户端用cv::imencode将Mat直接编码为std::vector<uchar>后发送;服务器端接收字节数组后用cv::imdecode直接解码为Mat,完全省去文件读写步骤。
  • 实现可靠的TCP读写函数:封装循环调用recv/send的函数,确保数据完全接收或发送。
  • 避免重复转换:服务器端接收file_size后只转换一次为整数,保存到变量中复用。
  • 减少数据复制:客户端直接读取文件到缓冲区,避免ostringstream和string的额外复制。

内容的提问来源于stack exchange,提问作者Aytunç Demir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:05:25