难道Linux的的剪接(2)从TCP套接字工作的时候拼接? [英] Does Linux's splice(2) work when splicing from a TCP socket?

查看:93
本文介绍了难道Linux的的剪接(2)从TCP套接字工作的时候拼接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一个有趣的小程序,在Linux上用C传输文件通过TCP。程序读取从插座的文件,并将其写入到文件(或反之亦然)。我原本是用来读/写和程序工作正常,但后来我了解到剪接并希望给它一个尝试。

I've been writing a little program for fun that transfers files over TCP in C on Linux. The program reads a file from a socket and writes it to file (or vice versa). I originally used read/write and the program worked correctly, but then I learned about splice and wanted to give it a try.

从标准输入(重定向文件)读写TCP套接字时,code我和剪接所写的作品完美,但与剪接从插槽读取和写入到标准输出时的errno设置为EINVAL立即失败。该名男子页指出,当既不描述符是一个管道(不是这样)EINVAL设置,偏移传递对于不能寻求(无偏移通过),或文件系统不支持拼接流,这使我我的问题:这是否意味着TCP可以从的拼接的管道,但不是的

The code I wrote with splice works perfectly when reading from stdin (redirected file) and writing to the TCP socket, but fails immediately with splice setting errno to EINVAL when reading from socket and writing to stdout. The man page states that EINVAL is set when neither descriptor is a pipe (not the case), an offset is passed for a stream that can't seek (no offsets passed), or the filesystem doesn't support splicing, which leads me to my question: does this mean that TCP can splice from a pipe, but not to?

我包括在我刚才做了一些错误的希望以下(减去错误处理$ C $三)code。它很大程度上基于对维基百科榜样剪接

I'm including the code below (minus error handling code) in the hopes that I've just done something wrong. It's based heavily on the Wikipedia example for splice.

static void splice_all(int from, int to, long long bytes)
{
    long long bytes_remaining;
    long result;

    bytes_remaining = bytes;
    while (bytes_remaining > 0) {
        result = splice(
            from, NULL,
            to, NULL,
            bytes_remaining,
            SPLICE_F_MOVE | SPLICE_F_MORE
        );

        if (result == -1)
            die("splice_all: splice");

        bytes_remaining -= result;
    }
}

static void transfer(int from, int to, long long bytes)
{
    int result;
    int pipes[2];

    result = pipe(pipes);

    if (result == -1)
        die("transfer: pipe");

    splice_all(from, pipes[1], bytes);
    splice_all(pipes[0], to, bytes);

    close(from);
    close(pipes[1]);
    close(pipes[0]);
    close(to);
}

在一个侧面说明,我认为以上将在第一个 splice_all 阻止时,该文件是足够大,由于管道填充(?),所以我也有一个版本的$ C $的c了 s到读取和同时管道写,但它具有相同的错误,因为这版本和更难阅读。

On a side note, I think that the above will block on the first splice_all when the file is large enough due to the pipe filling up(?), so I also have a version of the code that forks to read and write from the pipe at the same time, but it has the same error as this version and is harder to read.

编辑:我的内核版本为2.6.22.18-CO-0.7.3(在XP上运行coLinux的。)

My kernel version is 2.6.22.18-co-0.7.3 (running coLinux on XP.)

推荐答案

什么内核版本这是? Linux已经有拼接支持TCP套接字自2.6.25(提交<一个href=\"http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9c55e01c0cc835818475a6ce8c4d684df9949ac8\">9c55e01c0),所以,如果你使用的是早期的版本,你的运气了。

What kernel version is this? Linux has had support for splicing from a TCP socket since 2.6.25 (commit 9c55e01c0), so if you're using an earlier version, you're out of luck.

这篇关于难道Linux的的剪接(2)从TCP套接字工作的时候拼接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆