如何拼接到socketfd上?
How to splice onto socketfd?
提到的手册 splice()
可以在两个任意文件描述符之间传输数据,也可以传输到 socketfd 上。如果立即发送文件,则此方法有效。因此文件大小必须小于 PIPE_BUF_SZ (=65536).
但是,如何处理更大的文件?我想了解与 sendfile() 系统调用的区别。您将如何重写 sendfile()
系统调用?
第二次拼接returns与Invalid argument
。我猜是因为socketfd是不可搜索的。
size_t len = 800000; //e.g.
static int do_copy(int in_fd, int out_fd)
{
loff_t in_off = 0, out_off = 0;
static int buf_size = 65536;
off_t len;
int filedes[2];
int err = -1;
if(pipe(filedes) < 0) {
perror("pipe:");
goto out;
}
while(len > 0) {
if(buf_size > len) buf_size = len;
/* move to pipe buffer. */
err = splice(in_fd, &in_off, filedes[1], NULL, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
if(err < 0) {
perror("splice:");
goto out_close;
}
/* move from pipe buffer to out_fd */
err = splice(filedes[0], NULL, out_fd, &out_off, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
if(err < 0) {
perror("splice2:");
goto out_close;
}
len -= buf_size;
}
err = 0;
out_close:
close(filedes[0]);
close(filedes[1]);
out:
return err;
}
sendfile()
系统调用不检查文件描述符是否可查找。对该 fd 的唯一检查是,如果您可以将 (FMODE_READ) 读入 fd。
splice()
进行更多检查。其中,如果 fd 是可搜索的 (FMODE_PREAD) / (FMODE_PWRITE).
这就是为什么 sendfile 有效,但 splice 无效的原因。
提到的手册 splice()
可以在两个任意文件描述符之间传输数据,也可以传输到 socketfd 上。如果立即发送文件,则此方法有效。因此文件大小必须小于 PIPE_BUF_SZ (=65536).
但是,如何处理更大的文件?我想了解与 sendfile() 系统调用的区别。您将如何重写 sendfile()
系统调用?
第二次拼接returns与Invalid argument
。我猜是因为socketfd是不可搜索的。
size_t len = 800000; //e.g.
static int do_copy(int in_fd, int out_fd)
{
loff_t in_off = 0, out_off = 0;
static int buf_size = 65536;
off_t len;
int filedes[2];
int err = -1;
if(pipe(filedes) < 0) {
perror("pipe:");
goto out;
}
while(len > 0) {
if(buf_size > len) buf_size = len;
/* move to pipe buffer. */
err = splice(in_fd, &in_off, filedes[1], NULL, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
if(err < 0) {
perror("splice:");
goto out_close;
}
/* move from pipe buffer to out_fd */
err = splice(filedes[0], NULL, out_fd, &out_off, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
if(err < 0) {
perror("splice2:");
goto out_close;
}
len -= buf_size;
}
err = 0;
out_close:
close(filedes[0]);
close(filedes[1]);
out:
return err;
}
sendfile()
系统调用不检查文件描述符是否可查找。对该 fd 的唯一检查是,如果您可以将 (FMODE_READ) 读入 fd。
splice()
进行更多检查。其中,如果 fd 是可搜索的 (FMODE_PREAD) / (FMODE_PWRITE).
这就是为什么 sendfile 有效,但 splice 无效的原因。