AF_UNIX socket开销?

我看到一些奇怪的东西,一对AF_UNIX插座创建的呼叫,如:
socketpair(AF_UNIX,SOCK_STREAM,sfd);

其中sfd是文件描述符的int [2]数组。

首先,认缓冲区大小似乎是122K(124928字节),而不是/ proc / sys / net(如wmem_default,设置为128K)的任何东西。有没有人知道这个奇怪的缓冲区大小的原因?

第二,当通过套接字写入小消息(8字节)时。我只能在写入块之前写入其中的423个,这只有8 * 423 = 3384字节,另一个奇数的大小。这些消息的作用就好像它们每个占用了一点点字节一样。这个开销的来源是什么?

在RHEL6上运行(2.6.32,64位)

我写了一个程序来尝试不同大小的数据来比较间接成本:

#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,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,sfd);

    int 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);
    }
}

这使:

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

与管道相比,绝对有很多开销:

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
看看插座(7)手册页。有一个部分如下:

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.

所以看起来,开销仅仅是为了保存内核的簿记信息。

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...