我已經寫了一個有趣的小程序,在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