Linux 如何拼接到插座FD上?

Linux 如何拼接到插座FD上?,linux,linux-kernel,splice,Linux,Linux Kernel,Splice,上面提到的手册splice()可以在两个任意文件描述符之间传输数据,也可以在socketfd上传输数据。如果文件立即发送,则此操作有效。因此,文件大小必须小于PIPE_BUF_SZ(=65536) 但是,如何处理更大的文件?我想了解sendfile()系统调用的区别。如何重写sendfile()syscall 第二个拼接返回的参数无效。我猜这是因为socketfd不可查找 size_t len = 800000; //e.g. static int do_copy(int in_fd, int

上面提到的手册
splice()
可以在两个任意文件描述符之间传输数据,也可以在socketfd上传输数据。如果文件立即发送,则此操作有效。因此,文件大小必须小于PIPE_BUF_SZ(=65536)

但是,如何处理更大的文件?我想了解sendfile()系统调用的区别。如何重写
sendfile()
syscall

第二个拼接返回的参数
无效。我猜这是因为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;
}
size\u t len=800000//例如
静态int do_复制(int in_fd,int out_fd)
{
loff\u t in\u off=0,out\u off=0;
静态int buf_大小=65536;
关特伦;
int filedes[2];
int err=-1;
if(管道(filedes)<0){
佩罗尔(“管道:”);
出去;
}
而(len>0){
如果(buf_size>len)buf_size=len;
/*移动到管道缓冲区*/
err=拼接(in_fd和in_off,filedes[1],NULL,大小,拼接移动,拼接更多);
如果(误差<0){
perror(“拼接:”);
出去走走;
}
/*从管道缓冲区移动到out\u fd*/
err=拼接(filedes[0],NULL,out\u fd,&out\u off,buf\u大小,拼接移动,拼接更多);
如果(误差<0){
佩罗尔(“拼接2:”);
出去走走;
}
len-=buf_尺寸;
}
误差=0;
关闭:
关闭(filedes[0]);
关闭(filedes[1]);
输出:
返回错误;
}
sendfile()
systemcall不会检查文件描述符是否可查找。对fd的唯一检查是,如果您可以读取(FMODE_read)fd

splice()
执行更多检查。除其他外,如果fd是可查找的(FMODEPREAD)/(FMODEPWRITE)

这就是为什么sendfile可以工作,但splice不能工作。

sendfile()
systemcall不会检查文件描述符是否可查找。对fd的唯一检查是,如果您可以读取(FMODE_read)fd

splice()
执行更多检查。除其他外,如果fd是可查找的(FMODEPREAD)/(FMODEPWRITE)


这就是为什么sendfile可以工作,但splice不能工作的原因。

这来自手册页:`EINVAL目标文件系统不支持拼接;目标文件以追加模式打开;两个文件描述符均未提及管道;或为不可查找设备提供的偏移量。`Thx@vtha。如上所述,socketfd似乎是不可查找的。但是,sendfile()使用完全相同的设置+偏移量!据我所知,sendfile()或多或少是一个包装器,使用splice()。很有趣。我必须在我的工作站上测试它;目标文件以追加模式打开;两个文件描述符均未提及管道;或为不可查找设备提供的偏移量。`Thx@vtha。如上所述,socketfd似乎是不可查找的。但是,sendfile()使用完全相同的设置+偏移量!据我所知,sendfile()或多或少是一个包装器,使用splice()。很有趣。我必须在我的工作站上测试它。