【发布时间】:2016-02-09 13:15:52
【问题描述】:
我正在使用 OpenBSD netcat 测试文件传输,并注意到在 Ubuntu 而不是 Debian 上传输相同文件需要更多时间。使用 strace,我发现数据在 Ubuntu 上以 64k 块传输。
mgamal@ubuntu:~$ strace cat test | nc -vvvv 10.10.172.11 8888
...
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
另一方面,在 Debian 上:
mgamal@ubuntu:~$ strace cat test | nc -vvvv 10.10.172.11 8888
....
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
我在 Debian 上编写了以下代码来检查管道大小:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int pipefd[2];
int size;
int i;
pipefd[0] = STDIN_FILENO;
pipefd[1] = STDOUT_FILENO;
pipe(pipefd);
size = fcntl(pipefd[0], F_GETPIPE_SZ);
printf("%d\n", size);
size = fcntl(pipefd[1], F_GETPIPE_SZ);
printf("%d\n", size);
return 0;
}
运行它,它仍然报告 64k
mgamal@debian:~$ ./test
65536
65536
我还尝试使用 netcat 以外的其他工具进行检查。而且我仍然看到管道尺寸为 128k
root@debian:~# strace cat foo | less
...
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
我尝试检查 netcat、内核、glibc 的源包,以查看管道大小是否设置为 128k,或者是否有任何对 fcntl() 的调用改变了管道大小,但找不到跟踪。
为什么管道大小报告为 64k,而实际大小为 128k?
【问题讨论】:
-
部分答案unix.stackexchange.com/questions/11946/…。 OSX 管道被报告为动态更改 big 写入的大小...您是否尝试在发送期间的不同时间获取大小?
-
我在 Ubuntu 和 Debian 上都运行了答案中的脚本。两者都报告 64k,并且 0 字节写入超过 64k 的写入。
-
我在 debian 中下载了 bash 源代码包,再次看到没有 fcntl() 调用。
-
我还从程序中删除了 pipe() 调用。 Ran:
date | ./test | tee foo在 Debian 上仍然有 64k
标签: linux unix ubuntu debian pipe