讲师中心 微信公众号
AI工具推荐 视频效率加速

c++怎么在Linux下利用sendfile实现文件到Socket的极速传输【进阶】

风晨君_7162

风晨君_7162

发布时间:2026-03-24 20:43:03

|

498人浏览过

|

来源于php中文网

原创

能,但需满足两个硬性条件:src_fd必须是支持mmap的普通文件,dst_fd必须是支持sendfile的socket(如TCP/UDP);否则内核退化为内核态复制,失去零拷贝意义。

c++怎么在linux下利用sendfile实现文件到socket的极速传输【进阶】

sendfile 系统调用在 Linux 下能直接零拷贝传文件吗?

能,但必须满足两个硬性条件:src_fd 是普通文件(且支持 mmap),dst_fd 是 socket(且底层协议栈支持 sendfile,比如 TCP/UDP);不满足时内核会自动退化成内核态复制,失去零拷贝意义。

  • 常见错误现象:sendfile 返回成功但实测速度没提升,大概率是源 fd 来自 pipe、/proc 或加密文件系统(如 ecryptfs),这些不支持 page cache 直接转发
  • 检查方法:用 strace -e trace=sendfile64 ./your_program 看是否触发了 ENOSYS 或回退到 read/write 循环(strace 里出现大量 read 和 write 调用)
  • sendfile 不支持 TLS socket —— OpenSSL 的 SSL_write 或 gnutls_record_send 无法和 sendfile 协同,加密必须在用户态做

如何正确构造 sendfile 的参数组合?

关键不是“怎么写”,而是“谁来控制偏移和长度”。Linux 的 sendfile 默认修改 src_fd 的 file offset,但 socket 不能 seek,所以你要决定是让内核帮你推进读位置,还是自己管理。

  • 如果传整个文件且不关心并发读:把 offset 设为 nullptr,内核自动从当前 offset 开始并更新它
  • 如果要分片传输或支持断点续传:传入指向 off_t* 的指针,每次调用前手动设置起始偏移,sendfile 返回后该值会被更新为实际发送结束位置
  • count 不是“尽量发这么多”,而是“最多发这么多”——遇到信号中断、socket 缓冲区满、磁盘 I/O 阻塞都会提前返回,必须循环处理
  • 别传 STDIN_FILENO 或 STDOUT_FILENO 当 src_fd —— 它们不是 seekable regular file,sendfile 直接失败返回 EINVAL

为什么用了 sendfile 还卡在 write 等待?

因为 sendfile 只解决“数据从文件到 socket buffer”的拷贝问题,不解决“socket buffer 到网卡”的阻塞。TCP 拥塞窗口小、对端接收慢、本地发送缓冲区满,都会让 sendfile 阻塞(默认阻塞 socket)。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 典型表现:程序 hang 在 sendfile 调用,strace 显示 sendfile64(..., ..., ..., 1048576) = ? 卡住
  • 解法一:把 socket 设为非阻塞(fcntl(fd, F_SETFL, O_NONBLOCK)),然后检查 sendfile 返回值 —— 若为 -1 且 errno == EAGAIN || errno == EWOULDBLOCK,说明得等 POLLOUT
  • 解法二:用 SO_SNDBUF 调大 socket 发送缓冲区(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val))),但注意内核有上限(/proc/sys/net/core/wmem_max)
  • 别忽略 TCP_NODELAY:小文件或交互场景下,Nagle 算法会攒包,关掉它(setsockopt(..., IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))可减少延迟

sendfile 和 splice 对比:什么时候该换?

splice 更底层、更灵活,但要求两端都是 pipe 或支持 splice 的 fd(如 /dev/zero、eventfd),而 sendfile 是专为“文件→socket”优化的快捷路径。

立即学习“C++免费学习笔记(深入)”;

  • 如果你需要中转(比如文件 → pipe → socket),或者想绕过 page cache 做 direct I/O,splice 是唯一选择
  • sendfile 在 ext4/xfs 上稳定高效;但在 btrfs 或 overlayfs 上可能因 CoW 行为导致意外拷贝,此时 splice + open(..., O_DIRECT) 更可控
  • splice 不支持跨 mount point(比如文件在 NFS 上,socket 在本地),sendfile 同样受限 —— 这类场景只能老实用 read/write
  • 别试图用 splice 替代 sendfile 来“优化”简单文件传输 —— 多一层抽象、多一次 syscall、更难 debug

真正影响性能的往往不是 sendfile 本身,而是你有没有关掉 Nagle、设对 socket buffer、确认文件系统支持、以及是否在非阻塞模式下正确处理 EAGAIN。漏掉其中任何一个,零拷贝就只是个幻觉。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3628

2023.11.20

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6547

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2728

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

6636

2023.08.14

tcp和udp的区别
tcp和udp的区别

TCP和UDP的区别,在连接性、可靠性、速度和效率、数据报大小以及适用场景等方面。本专题为大家提供tcp和udp的区别的相关的文章、下载、课程内容,供大家免费下载体验。

563

2023.07.25

udp是什么协议
udp是什么协议

UDP是OSI参考模型中一种无连接的传输层协议。本专题为大家带来udp是什么协议的相关文章,免费提供给大家。

3231

2023.08.08

tcp和udp有什么区别
tcp和udp有什么区别

tcp和udp的区别有:1、udp是无连接的,tcp是面向连接的;2、udp是不可靠传输,tcp是可靠传输;3、udp是面向报文传输,tcp是面向字节流传输。想了解更多tcp相关的内容,可阅读本专题下面的相关文章。

3849

2024.11.14

Docker Desktop怎么设置端口映射
Docker Desktop怎么设置端口映射

本专题聚焦Docker Desktop容器端口映射与访问配置,整理从创建容器、设置端口绑定到验证本地服务访问的操作流程。针对端口被占用、映射配置错误、容器服务无法访问等情况,也提供相应的检查方向,方便用户完成端口配置。

0

2026.11.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn