Linux下的网络编程学习(十一):高级I/O函数(4):mmap和splice

mmap函数和munmap函数

  mmap函数用于申请内存空间。该空间可以作为进程间通信的共享内存,也可以将文件映射到该内存中。munmap函数是释放该空间。

#include<sys/mman.h>
void* mmap(void *start,size_t length,int prot , int flags,int fd,off_t offset);
int munmap(void *start,size_t length);

start:指定内存的起始地址,为NULL时,系统自动配置;
length:内存的长度。
prot: 用来设置内存段的访问权限;PROT_READ:内存可读;PROT_WRITE :内存可写;PROT_EXEC 内存段可执行;PROT_NONE: 内存段不能被访问。
flags:控制内存段内容被修改后的行为;MAP_SHARED:进程间共享这段内存,对该内存的修改将反映到被映射的文件中。MAP_PRIVATE:内存段位调用进程所私有,对该内存段的修改不会映射到文件中;MAP_ANONYMOUS:这段内存不是从映射过来的。其内容被初始化为0,可以省略后两个参数。
MAP_FIXED:内存段必须位于start参数指定的地址处,start是内存页面大小(4096)的整数倍.
MAP_HUGETLB:按照大内存页面分配内存空间。

splice函数

  splice函数用于描述两个文件描述符之间移动数据,也是零拷贝操作。

#include<fcntl.h>
ssize_t splice(int fd_in,loff_t* off_in,int fd_out,loff_t* off_out,size_t len , unsigned int flags);

fd_in:是待输入数据的文件描述符;若fd_in 是管道文件符,则off_in是NULL;如果fd_in不是管道文件符,则off_in表示从何处开始读取数据,若off_in被设置为NULL,表示输入数据流的当前偏移位置读入。
fd_out和off_out是用于输出数据流;
len:指定移动数据的长度;
flags:指控制如何移动数据
splice的flags常用值:
SPLICE_F_MOVE:若可以,则整页移动;
SPLICE_F_NONBLOCK:非阻塞的操作
SPLICE_F_MORE:给内核提示:后续调用splice读取更多的数据

使用splice函数实现的回射服务器:

#include<sys/sock.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<cstdio>
#include<cstdlib>
#include<unistd>
#include<cstring>
#include<fcntl.h>
#include<iostream>
 using namespace std;
 
 int main(int argc,char* argv[])
 {
	 if (argc < 2)
	 {
		 cout<<"usage :"<<basename(argv[0])<<"ip_address port_number"<<endl;
		 return 1;
		 
	 }
	 
	 const char * ip = argv[1];
	 int  port = atoi(argv[2]);
	 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 sock = socket(PF_INET,SOCK_STREAM,0);
	 assert(sock >= 0);
	 int ret = bind(sock,(struct sockaddr*) &address,sizeof(address));
	 assert(ret != -1);
	 struct sockaddr_in client;
	 socklen_t client_addrlength = sizeof(client);
	 int connfd = accept(sock,(struct sockaddr*)&client,&client_addrlength);
	 if(connfd < 0);
	 {
		 cout<<"errno is"<<errno;
		 
		 
	 }
	 else
	 {
		 int piped[2];
		 assert(ret != -1);
		 ret = pipe(piped);
		 ret = splice(connfd, NULL,piped[1],NULL,321786,SPLICE_F_MORE|SPLICE_F_MOVE);
		 assert(ret != -1);
		 ret  = splice(piped[0],NULL,connfd,NULL,321786,SPLICE_F_MORE|SPLICE_F_MOVE);
		 assert(ret != -1);
		 close(connfd);
		 
		 
	 }
	 close(sock);
	 return 0 ;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值