setsockopt SO_SNDBUF及其在unix域中的行为

时间:2016-12-08 02:07:53

标签: c linux sockets unix-socket

我有一个测试unix域服务器,它具有以下SO_SNDBUF设置为1024000 连接进来时:

for ( ; ; ) {
    connfd = accept(fdfromps, 0, 0);

    int new_size = 1024000 ;
    setsockopt(connfd, SOL_SOCKET, SO_SNDBUF , &new_size, sizeof(new_size));

    SetSocketBlockingEnabled(connfd,false) ;
    FDArray[connfd] = 1 ;
} //for 

还将此fd设置为非阻塞

客户端不会收回服务器发送给客户端的任何包,所以我 可以在服务器发送遇到错误时测量计数器(errno = 11), 来源如下:

测试1:

strcpy(msg,"1234567890");

测试2:

sprintf(msg,"%s%s%s%s%s",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890") ;

和测试代码:

sprintf(strsend,"%04d%s",strlen(msg),msg) ;
int icnt = 0 ;
pthread_detach(pthread_self());
while( 1 ){
    for(int idx=0;idx<20;idx++){
        if( FDArray[idx] == 1 ){
            int nread = send(idx,strsend,strlen(strsend),MSG_NOSIGNAL);
            if( nread < 0 ){
                printf("send to (%d) ...errno=(%d) \n",idx,errno );
                FDArray[idx] = 0 ;
            }else{
                printf("send to (%d) ... nread=(%d) \n", idx ,nread ) ;
                ++icnt ;
            }
        }
    }
    printf("......(%d) \n",icnt) ;
    usleep( 10000 ) ;
}

Test1,其中msg有14个字节,icnt是2667,Test2有msg有504个字节, icnt是1600。

我对数字2667和1600感到困惑,因为504字节远远超过 14个字节,我希望Test2的icnt应该比Test1中的icnt大得多, 有什么可以解释的吗?!

环境:

sysctl -a | grep "mem"

net.core.rmem_default = 212992
net.core.rmem_max = 1024000
net.core.wmem_default = 212992
net.core.wmem_max = 1024000

uname -a

3.10.0-327.el7.x86_64

编辑:

    int res = 0 ;
    optlen = sizeof(sendbuff);
    getsockopt(connfd, SOL_SOCKET, SO_SNDBUF , &sendbuff, &optlen);
    if(res == -1)
        printf("Error getsockopt one");
     else
         printf("send buffer size = %d\n", sendbuff);

    int new_size = 512000 ;
    setsockopt(connfd, SOL_SOCKET, SO_SNDBUF , &new_size, sizeof(new_size));
    getsockopt(connfd, SOL_SOCKET, SO_SNDBUF , &sendbuff, &optlen);
    if(res == -1)
        printf("Error getsockopt one");
     else
         printf("send buffer size = %d\n", sendbuff);

编辑2:

ss -ax | grep "testud"  ## testud  is the nnix domain name

将显示Send-Q大约1024000,非阻塞发送get errno = 11 从那以后,这就是我观察到的,不知道它会有所帮助。

1 个答案:

答案 0 :(得分:0)

内核可以向上或向下调整SO_SNDBUF值。设置后尝试使用getsockopt()获取它,看看它实际上是什么。