管道
是的,非阻塞容量通常为4KB,但是为了最大的可移植性,您最好使用PIPE_BUF
常量。另一种选择是使用非阻塞I/O。
有关更多信息,请参见man 7 pipe
。
Unix数据报套接字
使用数据报套接字上的send
函数进行写入确实保证是原子操作。在Linux中,它们也是可靠的,并且保持排序。(这使得最近引入的SOCK_SEQPACKET
对我来说有些令人困惑)有关此问题的许多信息都在man 7 unix
中。
最大数据报大小取决于套接字。可以使用getsockopt/setsockopt
获取SO_SNDBUF
的值。在Linux系统上,它的范围介于2048和wmem_max
之间,默认值为wmem_default
。例如,在我的系统上,wmem_default = wmem_max = 112640
。(您可以从/proc/sys/net/core
中读取它们)关于此的大部分相关文档都在man 7 socket
中,围绕着SO_SNDBUF
选项。我建议您自己阅读,因为它所描述的容量翻倍行为起初可能有点令人困惑。
流和数据报之间的实际区别
流套接字只在连接状态下工作。这主要意味着它们只能与一个对等方通信。作为流,它们不能保证保留"消息边界"。
数据报套接字是未连接的。它们可以(理论上)同时与多个对等体通信。它们保留消息边界。
[我想新的SOCK_SEQPACKET
介于两者之间:已连接并且保留边界。]
在Linux上,两者都是可靠的,并保持消息排序。如果您使用它们来传输流数据,它们往往表现类似。所以只需使用匹配您的流的那个,并让内核为您处理缓冲。
比较流、数据报和管道的简单基准测试:
socat UNIX-LISTEN:u OPEN:/dev/null &
until [[ -S u ]]; do :;done
time socat OPEN:large-file UNIX-CONNECT:u
socat UNIX-RECV:u OPEN:/dev/null &
until [[ -S u ]]; do :;done
time socat OPEN:large-file UNIX-SENDTO:u
socat PIPE:p,rdonly=1 OPEN:/dev/null &
until [[ -p p ]]; do :;done
time socat OPEN:large-file PIPE:p
这里没有任何显著的统计数据。我的瓶颈可能是读取大文件。