高级I/O函数(2)-splice函数
splice函数:
功能描述:用于在两个文件描述符之间移动数据,也是零拷贝操作。函数定义如下:
#include <fcntl.h>
ssize_t splice(int fd_in,loff_t* off_t,int fd_out,loff_t* off_out,size_t len,unsigned int flags);
参数描述:
fd_in:待输入数据的文件描述符.
off_t:如果fd_in是一个管道文件描述符,那么off_t参数必须是NULL,表示从数据流的当前偏移位置读入;如果fd_in不是一个管道文件描述符(例如socket),则它将指出具体的偏移位置.
len:指定移动数据的长度.
flags:则控制数据如何移动,它可以被设置为下表中值的按位异或.
表 splice的flags参数的常用取值及其含义
| 常用值 | 含义 |
| SPLICE_F_MOVE | 如果合适的话,按整页内存移动数据. |
| SPLICE_F_NONBLOCK | 非阻塞的splice操作,但实际效果还是会受文件描述符本身的阻塞状态的影响. |
| SPLICE_F_MORE | 给内核一个提示:后续的splice调用将读取更多的数据 |
| SPLICE_F_GIFT | 对splice没有效果. |
注意:
使用splice函数时,fd_in和fd_out必须至少有一个管道文件描述符.调用成功后返回移动字节的数量.它可能返回0,这发生从管道中读取数据时而该管道没有被写入任何数据.错误返回-1并设置errno.
例子:利用splice函数来实现一个零拷贝的回射服务器模型。
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h> int main(int argc,const char* argv[]){
if(argc!=){
printf("usage:%s ip_address port_number\n",argv[]);
return -;
}' const char* ip=argv[];
int port=atoi(argv[]); int ret;
struct sockaddr_in address;
bzero(&address,sizeof(address));
address.sin_family=AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port=htons(port); int sockfd=socket(AF_INET,SOCK_STREAM,);
assert(sockfd!=-); ret=bind(sockfd,(struct sockaddr*)&address,sizeof(address));
assert(ret!=-); ret=listen(sockfd,);
assert(ret!=-); while(){
struct sockaddr_in peer;
bzero(&peer,sizeof(peer));
socklen_t len=sizeof(peer); int connfd=accept(sockfd,(struct sockaddr*)&peer,len);
if(connfd<){
printf("errno is:%d\n",errno);
break;
}
else{
int pipefd[];
ret=pipe(pipefd);
assert(ret!=-); /*将connfd上流入的客户端数据定向到管道中*/
ret=splice(connfd,NULL,pipefd[],NULL,,SPLICE_F_MORE|
SPLICE_F_MOVE);
assert(ret!=-);
/*将管道中的数据定向到connfd的客户端文件描述符上*/
splice(pipefd[],NULL,connfd,NULL,,SPLICE_F_MORE|
SPLICE_F_MOVE);
assert(ret!=-);
}
} close(connfd);
close(sockfd);
return ;
}
我们通过splice函数将从客户端的内容读入到pipefd[1]中,然后再使用splice函数从pipefd[0]中读出该内容到客户端。从而实现了简单高效的回射服务。整个过程为执行recv/send操作,因此未涉及用户空间和内核空间之间的数据拷贝。
高级I/O函数(2)-splice函数的更多相关文章
- splice()函数,'SPLICE_F_MOVE' 'SPLICE_F_NONBLOCK' 'SPLICE_F_MORE' undeclared
1.编译含有splice()函数的程序时出现,'SPLICE_F_MOVE' undeclared,'SPLICE_F_NONBLOCK' ‘SPLICE_F_MORE' 也是一样undeclare ...
- linux网络编程九:splice函数,高效的零拷贝
from:http://blog.csdn.net/jasonliuvip/article/details/22600569 linux网络编程九:splice函数,高效的零拷贝 最近在看<Li ...
- splice()函数的使用方法
splice()函数的使用方法,这是一个拗口的函数.用起来有点麻烦.图3所看到的是splice函数的功能.将一个列表插入到还有一个列表其中.list容器类定义了splice()函数的3个版本号: sp ...
- js splice函数 数组增加,替换,删除
splice函数参数介绍: 第一个参数: 对于数数组的操作起始位置. 第二个参数: 从第一个参数开始,删除数组中的个数. 从第三个参数之后所有参数(如果有):执行完第二步之后,都插入到第一个参数的起始 ...
- ZOJ 4016 Mergeable Stack(利用list模拟多个栈的合并,STL的应用,splice函数!!!)
Mergeable Stack Time Limit: 2 Seconds Memory Limit: 65536 KB Given initially empty stacks, ther ...
- linux网络编程:splice函数和tee( )函数高效的零拷贝
splice( )函数 在两个文件描述符之间移动数据,同sendfile( )函数一样,也是零拷贝. 函数原型: #include <fcntl.h> ssize_t splice(int ...
- js数组的splice函数
一直没搞懂数组的splice函数,今天稍微测试了一下,了解了它的功能,在这里记录一下 1.测试 测试① var a = [1,2,3]; console.info(a.splice(1,1)); co ...
- 用 splice 函数分别实现 push、pop、shift、unshift 的方法
主要需要注意的是不同方法他们本身返回的值应该是什么,是数组当前的长度,还是取出的元素的值,再在splice函数里面进行相应的return就可以了.具体如下: 用 splice函数实现 push方法 f ...
- Codeforces 1131 F. Asya And Kittens-双向链表(模拟或者STL list)+并查集(或者STL list的splice()函数)-对不起,我太菜了。。。 (Codeforces Round #541 (Div. 2))
F. Asya And Kittens time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
随机推荐
- 提升PHP速度的53个建议
1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.$row[’id’] 的速度是$row[id]的7倍. 3.echo 比 print 快,并且使用e ...
- ubuntu下的c/c++环境搭建
原文地址:http://www.cnblogs.com/hitwtx/archive/2011/12/03/2274556.html ubuntu下的c/c++环境搭建是比较简单,因为有apt和新立得 ...
- DEDE数据库修改
dede数据库配置文件所在路径为:/data/common.inc.php 修改方法: 下面是该dede数据库配置文件的内容: <?php //数据库连接信息 $cfg_dbhost = 'lo ...
- destoon系统商城加淘宝客按钮方法
destoon系统很多喜欢运营B2B的站长都在用,其中的商城模块常常被用来做淘宝客,其中的难点是如何把购买按钮做成淘宝客地址,这个问题的修改在论坛上被叫价50元,下面小编把这个实用的方法分享下,希望对 ...
- HTML&CSS基础学习笔记1.9-添加图片
<img>标签是用来添加图片的~ <img>标签的使用方法:<img src="图片的地址"> 先来看段实例代码: <!DOCTYPE h ...
- C程序设计语言练习题1-7
练习1-7 编写一个打印EOF的值的程序. #include <stdio.h> // 包含标准库的信息. int main() // 定义名为main的函数,它不接受参数值. { // ...
- 编写Swift代码的其他工具
Swift程序不能在Windows其他平台编译和运行,有人提供了一个网站swiftstub.com,左栏是代码编辑窗口,右栏是运行结果窗口.可以在任何平台下编译和运行Swift程序.
- 如何在Ubuntu安装*.exe文件
下载及安装 若你使用 Debian 或者 Ubuntu 之类的发行版,只需要一个命令即可完成安装: apt-get install wine 若你使用的为其他发行版,请访问 http://winehq ...
- Eclipse远程调试weblogic
http://www.cnblogs.com/dyllove98/archive/2013/08/06/3241140.html http://blog.csdn.net/afgasdg/articl ...
- linux虚拟机命令行模式下,某些命令显示乱码问题。
刚安装了linux虚拟机,使用vi命令试着修改IP配置,结果出现乱码.配置IP的文件内容本身没有乱码,主要是vi编辑的命令行的提示出现乱码,例如,按i是插入模式,结果底下出现乱码提升,不是提示插入. ...