我已经写了一个有趣的小程序,在Linux上使用C传输文件通过TCP。程序从套接字读取文件并将其写入文件(反之亦然)。我最初使用读/写和程序工作正常,但后来我了解到splice,并想尝试一下。当从TCP套接字拼接时,Linux的拼接(2)是否工作?
当从stdin(重定向文件)读取并写入TCP套接字时,我使用splice编写的代码完美工作,但在从套接字读取并写入stdout时,立即使用拼接设置errno到EINVAL失败。该男子页指出,当既不描述符是管道(不是这样)EINVAL设置,偏移传递对于不能寻求(无偏移通过),或文件系统不支持拼接流,这使我我的问题:这是否意味着TCP可以拼接从管道,但不到?
我包括在我刚才做了一些错误的希望下面的代码(减去错误处理代码)。它主要依据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
块时该文件是足够大,由于管填充(?),所以我也有一个版本的代码fork
的s同时读取和写入管道,但它与此版本有相同的错误,并且难以阅读。
编辑:我的内核版本为2.6.22.18共0.7.3(在XP上运行coLinux的。)
我成功地在Haskell中使用`splice`:http://stackoverflow.com/questions/10080670/using-gnu-linux-system-call-splice-for-zero-copy-socket-to-socket-data-转让以及:) – 2012-04-10 11:37:46