相关疑难解决方法(0)

哪些文件系统支持通过Linux的拼接进行拼接(2)?

系统调用手册页splicesplice可能会失败并设置errnoEINVAL:

目标文件系统不支持拼接; 描述符都不是指管道; 或不可寻找设备的偏移量

哪些文件系统支持拼接?

c linux filesystems splice zero-copy

18
推荐指数
1
解决办法
2192
查看次数

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

我一直在编写一个有趣的程序,可以在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"); …
Run Code Online (Sandbox Code Playgroud)

c linux pipe

10
推荐指数
1
解决办法
6143
查看次数

两个TCP套接字之间的基于内核(Linux)的数据中继

我写的TCP中继服务器就像对等路由器(超级节点)一样工作.

最简单的情况是两个打开的套接字和它们之间的数据中继:

clientA <---> server <---> clientB

然而,服务器必须服务大约2000个这样的AB对,即.4000个插座......

userland中有两个众所周知的数据流中继实现(基于socketA.recv() - > socketB.send()socketB.recv() - > socketA.send()):

  • 使用select/poll函数(非阻塞方法)
  • 使用线程/分叉(阻塞方法)

我使用线程,所以在最坏的情况下服务器创建2*2000个线程!我不得不限制堆栈大小,它的工作原理,但它是正确的解决方案吗?

我的问题的核心:

有没有办法避免用户区中两个套接字之间的活动数据中继?

似乎有一种被动的方式.例如,我可以从每个套接字创建文件描述符,创建两个管道并使用dup2() - 与stdin/out重定向相同的方法.然后两个线程对数据中继没用,可以完成/关闭. 问题是服务器是否应该关闭套接字和管道以及如何知道管道何时损坏以记录事实?

我也发现了"套接字对",但我不确定它是否符合我的目的.

你会建议什么解决方案来卸载用户空间并限制线程数量?

一些额外的解释:

  • 服务器已定义静态路由表(例如ID_A与ID_B - 配对标识符).客户端A连接到服务器并发送ID_A.然后服务器等待客户端B.当A和B配对(两个套接字都打开)时,服务器启动数据中继.
  • 客户端是对称NAT背后的简单设备,因此N2N协议或NAT遍历技术对于它们而言过于复杂.

感谢Gerhard Rieger,我有一个提示:

我知道有两种内核空间方法可以避免在用户空间中进行读/写,recv/send:

  • 发送文件
  • 拼接

两者都有关于文件描述符类型的限制.

dup2无助于在内核中执行某些操作,AFAIK.

手册页:splice(2) splice(2) vmsplice(2) sendfile(2) tee(2)

相关链接:

sockets kernel tcp splice

6
推荐指数
1
解决办法
4627
查看次数

标签 统计

c ×2

linux ×2

splice ×2

filesystems ×1

kernel ×1

pipe ×1

sockets ×1

tcp ×1

zero-copy ×1