fasthttp 中如何使用 linux 系统调用 `sendfile`
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
接上一篇:fasthttp 中如何使用Transfer-Encoding: chunked 方式的流式内容输出
首先是找了一个库,封装了 linux 下的 sendfile 系统调用:github.com/hslam/sendfile
上代码:
- go.mod 中:
replace (
github.com/valyala/fasthttp => github.com/ahfuzhang/compress v1.49.2
)
package main
import (
"bufio"
"bytes"
"fmt"
"io"
syslog "log"
"net"
"os"
"strconv"
"time"
"github.com/hslam/sendfile"
"github.com/valyala/bytebufferpool"
"github.com/valyala/fasthttp"
)
var fileToSend *os.File
var fileSize int64
func FasthttpHandler(ctx *fasthttp.RequestCtx) {
ctx.HijackSetNoResponse(true) // 不使用 fasthttp 框架的输出
//ctx.Hijack(func(c net.Conn) { // 这里会 go 出来一个协程执行 hijack 回调函数。 我改了一个版本,不配置就不会 go 出来协程
// log.Println("do nothing")
//})
//
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
buf.Reset()
buf.B = append(buf.B, "HTTP/1.1 200 OK\r\n"+
"Server: fasthttp\r\n"+
"Date: Thu, 26 Oct 2023 01:09:23 GMT\r\n"+
"Content-Type: text/plain\r\n"+
"Cache-Control: no-cache, no-store, must-revalidate\r\n"+
"Transfer-Encoding: chunked\r\n"+
"\r\n"...)
conn := ctx.Conn()
_, _ = conn.Write(buf.B) // 写 http 头
//
for i := 0; i < 9; i++ {
_, _ = conn.Write([]byte(fmt.Sprintf("%x\r\n%d \r\n", 1, i)))
}
//
_, _ = conn.Write([]byte(fmt.Sprintf("%x\r\n", fileSize, i)))
n, err := sendfile.SendFile(ctx.Conn(), int(fileToSend.Fd()), 0, fileSize) // 使用系统调用
if err != nil {
syslog.Fatalln(err)
}
_, _ = conn.Write([]byte("\r\n"))
syslog.Println("send count:", n)
// 写入结束信息
_, _ = conn.Write([]byte("0\r\n\r\n")
}
func main() {
fileToSend, _ = os.Open("xxxx.file")
fileSize = 1024*2
//
syslog.SetFlags(syslog.Lshortfile | syslog.LstdFlags)
server := &fasthttp.Server{
Handler: FasthttpHandler,
}
syslog.Fatalln(server.ListenAndServe(":8089"))
}
相比直接从内存中 send 数据,实际测试中并未发现明显的性能提升,也可能是我只使用了 2kb 的数据,差异不明显。
希望对大家有用, have fun
fasthttp 中如何使用 linux 系统调用 `sendfile`的更多相关文章
- linux内核系统调用--sendfile函数
在apache,nginx,lighttpd等webserver其中,都有一项sendfile相关的配置,在一些网上的资料都有谈到sendfile会提升文件传输性能,那sendfile究竟是什么呢?它 ...
- 如何在Linux中添加新的系统调用
系统调用是应用程序和操作系统内核之间的功能接口.其主要目的是使得用户 可以使用操作系统提供的有关设备管理.输入/输入系统.文件系统和进程控制. 通信以及存储管理等方面的功能,而不必了解系统程序的内部结 ...
- [Linux]Linux系统调用列表
本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...
- 常用的Linux系统调用命令
常用的Linux系统调用命令 下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别. 一.进程控制 ...
- Linux系统调用(转载)
目录: 1. Linux系统调用原理 2. 系统调用的实现 3. Linux系统调用分类及列表 4.系统调用.用户编程接口(API).系统命令和内核函数的关系 5. Linux系统调用实例 6. Li ...
- Linux系统调用列表
转自Linux系统调用列表 一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtabl ...
- UNIX环境高级编程——Linux系统调用列表
以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完 ...
- Linux系统调用列表(转)
以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完 ...
- linux内核剖析(六)Linux系统调用详解(实现机制分析)
本文介绍了系统调用的一些实现细节.首先分析了系统调用的意义,它们与库函数和应用程序接口(API)有怎样的关系.然后,我们考察了Linux内核如何实现系统调用,以及执行系统调用的连锁反应:陷入内核,传递 ...
- 网络常用的linux系统调用
网络之常用的Linux系统调用 下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别. 一.进程控制 fo ...
随机推荐
- 1个案例读懂——游戏产品如何用 A/B 测试做增长
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着国内游戏用户数量趋于饱和,中国游戏产业也从高速成长期逐渐转型,市场成熟度提升,竞争趋于精细化. 随着游戏出海以 ...
- MyBatis batchInsert 批量插入数据
mybatis 是一个 Java 的持久层框架,它支持定制化 SQL.存储过程以及高级映射.通过 MyBatis,开发者可以直接编写原生态 SQL,避免了 JDBC 代码的繁琐. 如何在 MyBati ...
- MyBatis 核心组件 —— Configuration
概述 Mybatis 的核心组件如下所示: Configuration:用于描述 MyBatis 的主配置信息,其他组件需要获取配置信息时,直接通过 Configuration 对象获取.除此之外,M ...
- Java 日志框架学习笔记
日志概念 1. 日志文件 日志文件是用于记录系统操作事件的文件集合 1.1 调试日志 1.2 系统日志 系统日志是记录系统中硬件.软件和系统问题的信息,同时还可以监视系统中发生的事件.用户可以通过它来 ...
- 重磅 | Hugging Face 第一本中文图书正式出版!
Hugging Face 为机器学习从业者们提供了一个协作和交流的平台,你可以在 Hugging Face Hub 上开源自己的机器学习模型.数据集或者创建机器学习应用等,Hugging Face 还 ...
- 入门篇-其之七-Java运算符(下)
一.三元运算符的使用 三元运算符(也称作三目运算符),使用:和?表示,其格式为:布尔表达式 ? 表达式1 : 表达式2 如果布尔表达式的计算结果是true,那么执行表达式1:否则,如果布尔表达式的计算 ...
- win32com报错:无效的类字符串(Invalid Class String)
异常:无效的类字符串 (Invalid Class String) . 使用python操作COM组件的朋友应该都碰到过,这个报错来自于python标准库pythoncom.win32com也是建立在 ...
- 【调试】GDB使用总结
启动 在shell下敲gdb命令即可启动gdb,启动后会显示下述信息,出现gdb提示符. ➜ example gdb GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1 Cop ...
- 30 秒使用 Sealos 搭建个人密码管理器 Vaultwarden
我与 LastPass 的曲折恋情 超过 8 年网龄的我,注册过很多网站帐号,每个网站的密码我都用不同的复杂密码.一开始我全靠脑力记忆这些密码,后来渐渐觉得记起来很困难,就记录在笔记本上.但是随着时间 ...
- 在Python中使用Process创建子进程遇到的问题
假如使用Process创建子进程,那么在最后的函数调用时需要加上if __name__ == "__main__":语句,否则会报错. 未使用该语句 代码示例 from multi ...
