首页 > 编程知识 正文

函数前加o,send函数返回值

时间:2023-05-05 15:02:53 阅读:19386 作者:3827

sendfile函数通过在两个文件描述符之间传递数据(完全在内核中运行),避免了内核缓冲区和用户缓冲区之间的数据复制,并且非常高效,称为零拷贝。 函数定义如下:

# includesys/sendfile.hs size _ ts enfile (in tout _ FD,int in_fd,off_t* offset,size_t count );in_fd参数是待读出内容的文件描述符,out_fd参数是待写入内容的文件描述符。offset参数指定从读入文件流的哪个位置开始读,如果为空,则使用读入文件流默认的起始位置。count参数指定文件描述符in_fd和out_fd之间传输的字节数。

in_fd必须是支持类似于mmap的函数的文件描述符。 也就是说,它必须指向实际文件,而不是套接字或管道。 此外,out_fd必须是套接字。 首先,让我们来看看传统的读/写方法传输套接字。

需要传输文件时,具体流程详细情况如下。

1 )调用read函数,将文件数据copy返回内核缓冲区2 ) read函数,将文件数据从内核缓冲区copy调用到用户缓冲区3 )3:write函数,将文件数据调用到用户缓冲区copy还是在这个过程中发生了四次复制操作。

硬盘-内核-用户-套接字缓冲区-内核-协议引擎。

sendfile的工作原理如何?

1、系统调用sendfile ()通过DMA将硬盘数据复制到kernel buffer,然后数据通过kernel直接复制到另一个socket相关的kernel buffer。 这里没有用户状态和核心状态之间的切换,而是直接在内核中将一个错误复制到另一个错误。

2、DMA将数据从kernel buffer直接复制到协议栈,无切换,从用户状态和核心状态不需要数据。 因为数据在kernel上。

测试代码:

# includesys/socket.h # includenetinet/in.h # include arpa/inet.h # includesignal.h # include unistd.h # include include fcntl.h # includesys/stat.h # includesys/types.h # include error char * argv [ ] (if (argc=3) ) printf () 返回1; } const char* ip=argv[1]; 导入=atoi (argv [2]; const char* file_name=argv[3]; intfileFD=open(file_name,O_RDONLY; 资产(文件软盘0; 结构开始stat _ buf; stat (文件软盘,stat_buf ); 结构sockaddr _ in address; bzero (地址,sizeof )地址); address.sin_family=AF_INET; inet_Pton(af_inet,ip,address.sin_addr ); address.sin_port=htons(port; intsock=socket(pf_inet,SOCK_STREAM,0 ); ssert(sock=0); intret=bind(sock,) struct sockaddr* (地址,sizeof )地址); 资产(ret!=-1; ret=Listen(sock,5 ); 资产(ret!=-1; struct sockaddr_in client; socklen _ t client _ addr length=sizeof (client; intconnfd=accept(sock,(struct sockaddr* )客户端,client_addrlength ); if(connfd0) printf (错误is % d (n ),错误); }else{sendfile(connfd,filefd,NULL,stat_buf.st_size ); 关闭(connfd ); }关闭(sock ); 返回0; }然后进行

在另一个虚拟机上运行telnet

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。