原型:
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
说明:
第 1 个参数 out_fd,在 2.6 内核里,必须指向一个 socket 。
第 2 个参数 in_fd,是一个要拷贝文件的文件描述服。
第 3 个参数 offset, 是一个偏移量,它在不断的 sendfile 中,这个偏移量会随着偏移增加,直到文件发送完为止,当然在程序中需要用如 while() 这样的语句来控制。
第 4 个参数 count,表示要传送的字节数(在以下示例中,是 1G 文件的大小,即 buf.st_size)。
应用举例:
下面使用 sendfile() 拷贝一个 1G 大小的文件,程序分为客户端和服务端。
服务端代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/sendfile.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main (int argc, char **argv)
{
struct sockaddr_un sin1;
int server_sockfd, client_sockfd;
int server_len, client_len;
ssize_t bytes, res=0;
ssize_t rtotal = 0;
FILE *stream;
int in_fd;
struct stat buf;
off_t off = 0;
unlink ("server_socket");
unlink ("src_sendfile_save");
stream = fopen ("src_sendfile_save", "w");
if (!stream) {
perror ("fopen");
exit (EXIT_FAILURE);
}
fclose (stream);
if ((in_fd = open ("src", O_RDONLY)) < 0) {
printf ("Can't open 'src' file");
exit (EXIT_FAILURE);
}
if (fstat (in_fd, &buf) == -1) {
printf ("Can't stat 'src' file\n");
exit (EXIT_FAILURE);
}
printf ("Get file size are %u bytes\n", buf.st_size);
server_sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
if (server_sockfd < 0) {
perror ("socket");
exit (EXIT_FAILURE);
}
sin1.sun_family = AF_UNIX;
strcpy (sin1.sun_path, "server_socket");
server_len = sizeof (sin1);
if (bind (server_sockfd, (struct sockaddr *)&sin1, server_len) < 0) {
perror ("bind");
exit (EXIT_FAILURE);
}
if (listen (server_sockfd, 5) < 0) {
perror ("listen");
exit (EXIT_FAILURE);
}
printf ("The server is waiting for client connect...\n");
client_sockfd = accept (server_sockfd, (struct sockaddr *)&sin1, (socklen_t *)&client_len);
if (client_sockfd == -1 ) {
perror ("accept");
exit (EXIT_FAILURE);
}
while (off < buf.st_size) {
if ((res = sendfile (client_sockfd, in_fd, &off, buf.st_size)) < 0 ) {
printf ("sendfile failed\n");
exit (EXIT_FAILURE);
} else {
rtotal += res;
}
}
printf ("server sendfile total %u bytes\n", rtotal);
close (client_sockfd);
unlink ("server_socket");
return (0);
}
客户端代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
struct sockaddr_un address;
int sockfd;
int len, result;
int i, bytes;
struct stat buf;
off_t off;
ssize_t res, total = 0;
int wfd;
char rwbuf[4096];
wfd = open ("src_sendfile_save", O_WRONLY);
if (wfd < 0) {
perror ("open");
exit (EXIT_FAILURE);
}
/*..socket,AF_UNIX....,SOCK_STREAM....*/
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror ("socket");
exit (EXIT_FAILURE);
}
address.sun_family = AF_UNIX;
strcpy (address.sun_path, "server_socket");
len = sizeof (address);
/*..........*/
result = connect (sockfd, (struct sockaddr *)&address, len);
if (result == -1) {
printf ("ensure the server is up\n");
perror ("connect");
exit (EXIT_FAILURE);
}
while ((res = read (sockfd, rwbuf, 4096)) > 0) {
total += res;
write (wfd, rwbuf, 4096);
}
printf ("total %u bytes received from server snedfile\n", total);
close (sockfd);
close (wfd);
return (0);
}
注:在我自己的测试中,对于拷贝 1G 大小的文件,使用 sendfile() 和 普通的 write() 差不多,没有明显区别。
转自:http://www.groad.net/bbs/read.php?tid-2308.html
分享到:
相关推荐
Python 第三方库 Sendkeys.whl,pip安装 先pip install wheel 再安装 pip install SendKeys-0.3-cp27-none-win_amd64.whl
SendKeys-0.3-cp27-none-win32
Socket下send和recv使用的说明及介绍
简单的TCP传输程序,对初级入门的学习者应该是很好的范例教材来的
linux专门为文件传输开放的API sendfile 比你自己写的文件传输程序速度快得多
用c#开发局域网的文件发送与接收,用oracle数据库实现,在数据中记录了文件的名称与文件在存储地址
sendfile 示例代码,理解sendfile的好参考
environment based on the udp protocol c++ language program cycle
socket文件传输收发文件,局域网tcp传输文件和视频
python 实现文件传输 课程设计 file_transfer 包括 计算机网络课程设计 Receive File Send File Tests Test Send File 接收文件 发送文件 测试 测试发送文件
主要介绍了asp.net使用Socket.Send发送信息及Socket.SendFile传输文件的方法,结合实例形式分析了asp.net基于socket实现信息与文件传输的相关技巧,需要的朋友可以参考下
客户端和服务端操作流程 服务器端: socket() --> bind() --> listen() --> accept() ...socket() --> connect() --> send() --> close() 创建socket --> 连接指定服务器的IP/端口号–>向socket中写入信息–>关闭socket
pywinauto使用的一个模块,可以用来模块键盘鼠标操作
此类类似于PHP pecl的php http_send_file 看: 安装随着作曲家添加到您的“要求”部分: composer require diversen/http-send-file用法示例: use diversen\sendfile;$ s = new sendfile(); // if you don...
具有图形界面的程序,用于通过TCP / IP发送文件。
py27可用的SendKeys版本,该资源为.exe文件,安装方便快捷,安装前请保证你已经安装了python
在新线程里,创建监听listen_sock,socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))。 绑定端口 bind(listen_sock, (struct sockaddr*) &local_addr, sizeof(SOCKADDR_IN)), 等待连接,accept(listen_sock, (struct...
很多时候用户需要从网站下载文件,如果文件是可以通过一个固定链接公开获取的,那么我们只需将文件存放到 webroot下的目录里就好。但大多数情况下,我们需要做权限控制,例如下载 PDF 账单,又例如下载网盘里的档案...
在源码SendKeys-0.3.zip基础上修改,适用于python3,是源码,要编译安装