C Solaris 10:在更改套接字缓冲区时优雅地处理ENOBUFS错误

C Solaris 10:在更改套接字缓冲区时优雅地处理ENOBUFS错误,c,sockets,unix,solaris,portability,C,Sockets,Unix,Solaris,Portability,我偶然发现了Solaris 10套接字和其他Linux/*NIX套接字之间的一个特殊区别。例如: int temp1, rc; temp1 = 16*1024*1024; /* from config, a value greater than system limit */ rc = setsockopt( sd, SOL_SOCKET, SO_RCVBUF, &temp1, sizeof(temp1); 上述代码在所有系统(Linux、HP-UX和AIX)上都将具有rc==0,S

我偶然发现了Solaris 10套接字和其他Linux/*NIX套接字之间的一个特殊区别。例如:

int temp1, rc;
temp1 = 16*1024*1024;  /* from config, a value greater than system limit */
rc = setsockopt( sd, SOL_SOCKET, SO_RCVBUF, &temp1, sizeof(temp1);
上述代码在所有系统(Linux、HP-UX和AIX)上都将具有
rc==0
,Solaris 10除外。其他系统会自动将提供的值截断到允许的最大值。Solaris 10正常地失败,错误号==ENOBUFS指示配置错误

经过仔细考虑后,决定由于特定应用程序是关键的,而不是失败的,因此应尽可能优雅地继续工作:

  • 在日志文件中生成有关配置不匹配的警告(很简单,使用
    getsockopt()
    添加检查),然后
  • 尝试设置最大缓冲区大小(以获得任何可能的性能)
  • 2是我卡住了。在所有非Solaris系统上,我不需要做任何事情:套接字已经为我做了

    但在Solaris上,我不知道该怎么办。我在
    (setsockopt(…)=-1&&errno==ENOBUFS)
    条件下实现了一些琐碎的二分法来查找最大缓冲区大小,但它看起来很难看。(我也没有保存查找结果的上下文:对于配置如此糟糕的每个连接,都必须重复搜索。全局变量是有问题的,因为代码位于共享库中,并且是从MT应用程序使用的。)

    在Solaris 10上,是否有更好的方法使用sockets API检测允许的最大缓冲区大小


    有没有办法让Solaris的sockets API像其他系统那样截断该值?

    我目前无法访问Solaris 10系统,但根据,您可以使用
    ndd
    实用程序查询(并设置)TCP和UDP的配置缓冲区大小最大值:

    $ ndd -get /dev/tcp tcp_max_buf
    $ ndd -get /dev/udp udp_max_buf
    

    我不知道有C API,但可能
    ndd
    使用的东西已经公开了?

    很长时间没有使用solaris了-您能从/dev/tcp中获取tcp\u max\u buf吗?否则,一些黑客会使用“ndd-get/dev/tcp-tcp\u max\u buf”并以某种方式将其传递给pgm。是的。。。如果OpenSolaris与此相关,那么:tcps_max_buf只会被读取,而不会用作函数返回或写入变量。对一个(前)系统程序员来说,发现自己是一个严格兼容接口的牺牲品是相当讽刺的……问题是,似乎没有一种方法可以获得使用兼容接口所需的信息。再进一步看一下,您似乎不是第一个遇到这种情况的人。我对它进行了
    truss
    -ed,它进入
    /dev/tcp
    ,然后启动几个特定于流的
    ioctl()
    调用:I\u CANPUT和I\u STR。显然,I\u STR用于向流模块发送消息。这就是POSIX的结束——以及一些完全特定于Solaris的、文档不足的开始(找不到任何文档)。例如,
    mod\u prop\u info\u t
    甚至没有在
    /usr/include
    下声明。目前看来是行不通的。