AF_UNIX套接字的开销? [英] AF_UNIX socket overhead?
问题描述
我看到一对夫妇奇怪的东西有一对被调用创建AF_UNIX套接字如:
socketpair(AF_UNIX,SOCK_STREAM,0,SFD);
在哪里SFD是一个int [2]数组的文件描述符。
首先,默认缓冲区大小似乎正好122K(124928字节),而不是任何东西从/ proc / SYS /网(如被设置为128K wmem_default)。有谁知道这个奇怪的缓冲区大小的原因是什么?
二,通过插座(8字节)编写小消息时。我只能写块,这是只有8 * 423 = 3384字节,另一个奇怪的大小之前写他们的423。这些消息作为虽然他们正在采取的每个295 +一点点字节。这是什么开销的来源?
运行在RHEL6(2.6.32,64位)
我写了一个程序来尝试不同的数据大小,以比较间接成本:
的#include<&errno.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdint.h GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>#定义DATA_SIZE 4无效的run(为size_t大小){
INT SFD [2];
如果(socketpair(AF_UNIX,SOCK_STREAM,0,SFD)== -1){
PERROR(错误);
}
INT sndbuf,SBSIZE = sizeof的(sndbuf);
的getsockopt(SFD [0],SOL_SOCKET,SO_SNDBUF,&放大器; sndbuf,(socklen_t的*)及SBSIZE); 的printf(数据大小:ZD%\\ n,大小);
字符的buff【规格】;
为size_t写道= 0;
为(为size_t二= 0; II蛋白酶32768;ⅱ++){
如果((发送(SFD [0],浅黄色,大小,MSG_DONTWAIT)== -1)及及(错误号== EAGAIN)){
写=二;
打破;
}
} 的printf(中写道:ZD%\\ n,写); 如果(写!= 0){
INT BPM = sndbuf /写;
诠释哦= BPM - 大小; 的printf(字节/消息:%I \\ N,BPM);
的printf(开销:%I \\ N,哦);
的printf(\\ n);
} 关闭(SFD [0]);关闭(SFD [1]);
}诠释主(){
INT SFD [2];
socketpair(AF_UNIX,SOCK_STREAM,0,SFD); INT sndbuf,SBSIZE = sizeof的(sndbuf);
的getsockopt(SFD [0],SOL_SOCKET,SO_SNDBUF,&放大器; sndbuf,(socklen_t的*)及SBSIZE); 的printf(缓冲大小:%我的\\ n \\ n,sndbuf);
关闭(SFD [0]);关闭(SFD [1]); 为(为size_t二= 4;ⅱ&下; = 4096;ⅱ* = 2){
运行(二);
}
}
这给出了:
缓冲区大小:124928数据大小:4
写道:423
字节/消息:295
开销:291数据大小:8
写道:423
字节/消息:295
开销:287数据大小:16
写道:423
字节/消息:295
开销:279数据大小:32
写道:423
字节/消息:295
开销:263数据大小:64
写道:423
字节/消息:295
开销:231数据大小:128
写道:348
字节/消息:358
开销:230数据大小:256
写道:256
字节/消息:488
开销:232数据大小:512
写道:168
字节/消息:743
开销:231数据大小:1024
写道:100
字节/消息:1249
开销:225数据大小:2048
写道:55
字节/消息:2271
开销:223数据大小:4096
写道:29
字节/消息:4307
开销:211
与使用管道肯定有很多的开销:
数据大小:4
写道:16384
字节/消息:4
开销:0数据大小:8
写道:8192
字节/消息:8
开销:0数据大小:16
写道:4096
字节/消息:16
开销:0数据大小:32
写道:2048
字节/消息:32
开销:0数据大小:64
写道:1024
字节/消息:64
开销:0数据大小:128
写道:512
字节/消息:128
开销:0数据大小:256
写道:256
字节/消息:256
开销:0数据大小:512
写道:128
字节/消息:512
开销:0数据大小:1024
写道:64
字节/消息:1024
开销:0数据大小:2048
写道:32
字节/消息:2048
开销:0数据大小:4096
写道:16
字节/消息:4096
开销:0
看一看插座(7)手册页。还有,上面写着一个部分:
SO_SNDBUF
设置或获取以字节为单位的最大套接字发送缓冲区。内核双打这个值
(允许簿记开销空间),当它被使用的setsockopt(2)设置,并且这
倍值被的getsockopt返回(2)。默认值是由设置
的/ proc / SYS /网/核心/ wmem_default文件和最大允许值是由设置
的/ proc / SYS /网/核心/ wmem_max文件。此选项的最小值(加倍)值
2048
块引用>所以看来开销仅仅是持有记账内核信息。
I'm seeing a couple strange things with a pair of AF_UNIX sockets created by a call such as:
socketpair(AF_UNIX, SOCK_STREAM, 0, sfd);
Where sfd is an int[2] array for the file descriptors.
First, the default buffer size seems to be exactly 122K (124928 bytes), rather than anything from /proc/sys/net (such as wmem_default which is set to 128K). Does anyone know the cause of this strange buffer size?
Second, when writing small messages through the socket (8 bytes). I can only write 423 of them before the write blocks, which is only 8*423 = 3384 bytes, another odd size. The messages are acting as though they're taking up 295 + a little bytes each. What's the source of this overhead?
Running on RHEL6 (2.6.32, 64-bit)
I wrote a program to try different sizes of data to compare overhead costs:
#include <errno.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define DATA_SIZE 4 void run(size_t size) { int sfd[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) == -1) { perror("error"); } int sndbuf, sbsize = sizeof(sndbuf); getsockopt(sfd[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, (socklen_t*)&sbsize); printf("Data Size: %zd\n", size); char buff[size]; size_t wrote=0; for (size_t ii=0; ii < 32768; ii++) { if ((send(sfd[0], buff, size, MSG_DONTWAIT) == -1) && (errno == EAGAIN)) { wrote = ii; break; } } printf("Wrote: %zd\n", wrote); if (wrote != 0) { int bpm = sndbuf/wrote; int oh = bpm - size; printf("Bytes/msg: %i\n", bpm); printf("Overhead: %i\n", oh); printf("\n"); } close(sfd[0]); close(sfd[1]); } int main() { int sfd[2]; socketpair(AF_UNIX, SOCK_STREAM, 0, sfd); int sndbuf, sbsize = sizeof(sndbuf); getsockopt(sfd[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, (socklen_t*)&sbsize); printf("Buffer Size: %i\n\n", sndbuf); close(sfd[0]); close(sfd[1]); for (size_t ii=4; ii <= 4096; ii *= 2) { run(ii); } }
Which gives:
Buffer Size: 124928 Data Size: 4 Wrote: 423 Bytes/msg: 295 Overhead: 291 Data Size: 8 Wrote: 423 Bytes/msg: 295 Overhead: 287 Data Size: 16 Wrote: 423 Bytes/msg: 295 Overhead: 279 Data Size: 32 Wrote: 423 Bytes/msg: 295 Overhead: 263 Data Size: 64 Wrote: 423 Bytes/msg: 295 Overhead: 231 Data Size: 128 Wrote: 348 Bytes/msg: 358 Overhead: 230 Data Size: 256 Wrote: 256 Bytes/msg: 488 Overhead: 232 Data Size: 512 Wrote: 168 Bytes/msg: 743 Overhead: 231 Data Size: 1024 Wrote: 100 Bytes/msg: 1249 Overhead: 225 Data Size: 2048 Wrote: 55 Bytes/msg: 2271 Overhead: 223 Data Size: 4096 Wrote: 29 Bytes/msg: 4307 Overhead: 211
Versus using a pipe there's definitely a lot of overhead:
Data Size: 4 Wrote: 16384 Bytes/msg: 4 Overhead: 0 Data Size: 8 Wrote: 8192 Bytes/msg: 8 Overhead: 0 Data Size: 16 Wrote: 4096 Bytes/msg: 16 Overhead: 0 Data Size: 32 Wrote: 2048 Bytes/msg: 32 Overhead: 0 Data Size: 64 Wrote: 1024 Bytes/msg: 64 Overhead: 0 Data Size: 128 Wrote: 512 Bytes/msg: 128 Overhead: 0 Data Size: 256 Wrote: 256 Bytes/msg: 256 Overhead: 0 Data Size: 512 Wrote: 128 Bytes/msg: 512 Overhead: 0 Data Size: 1024 Wrote: 64 Bytes/msg: 1024 Overhead: 0 Data Size: 2048 Wrote: 32 Bytes/msg: 2048 Overhead: 0 Data Size: 4096 Wrote: 16 Bytes/msg: 4096 Overhead: 0
解决方案Take a look at the socket(7) man page. There is a section that reads:
SO_SNDBUF Sets or gets the maximum socket send buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/wmem_default file and the maximum allowed value is set by the /proc/sys/net/core/wmem_max file. The minimum (doubled) value for this option is 2048.
So it appears that the overhead is simply to hold bookkeeping information for the Kernel.
这篇关于AF_UNIX套接字的开销?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!