当前位置:  开发笔记 > 编程语言 > 正文

从TCP套接字拼接时,Linux的splice(2)是否有效?

如何解决《从TCP套接字拼接时,Linux的splice(2)是否有效?》经验,为你挑选了1个好方法。

我一直在编写一个有趣的程序,可以在Linux上用C语言通过TCP传输文件.程序从套接字读取文件并将其写入文件(反之亦然).我最初使用读/写和程序正常工作,但后来我学习了拼接,并想尝试一下.

我用splice编写的代码在从stdin(重定向文件)读取并写入TCP套接字时非常有效,但在从套接字读取并写入stdout时,会立即将splice设置errno设置为EINVAL.手册页指出当两个描述符都不是管道(不是这种情况)时,EINVAL被设置,为无法搜索的流传递偏移量(没有传递偏移量),或文件系统不支持拼接,这导致我我的问题:这是否意味着TCP可以拼接管道,而不是

我包括下面的代码(减去错误处理代码),希望我做错了.它主要基于维基百科的拼接示例.

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的文件因为管道填满(?)而在文件足够大时会阻塞,所以我还有一个代码版本fork可以从管道读取和写入同时,但它与此版本具有相同的错误,并且更难以阅读.

编辑:我的内核版本是2.6.22.18-co-0.7.3(在XP上运行coLinux.)



1> bdonlan..:

这个内核版本是什么?从2.6.25(提交9c55e01c0)开始,Linux已经支持从TCP套接字进行拼接,所以如果你使用的是早期版本,那你就不走运了.

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有