Solaris 10:在更改套接字缓冲区时正常处理ENOBUFS错误

时间:2010-09-13 15:24:03

标签: 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);

上面的代码在所有系统上都有rc == 0 - Linux,HP-UX和AIX - 除了Solaris 10.其他系统以静默方式将提供的值截断为允许的最大值。 Solaris 10 正确地失败,errno == ENOBUFS表示配置错误。

经过一番商议后,我们决定,由于特定的应用程序是关键的而不是失败的,所以它应该继续尽可能优雅地工作:

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

    但在Solaris上我无所适从。我已经在(setsockopt(...) == -1 && errno == ENOBUFS)条件下实现了一些微不足道的二分法来找到最大缓冲区大小,但它看起来很难看。 (我没有保存查找结果的上下文:对于每个具有这种错误配置的连接都必须重复搜索。全局变量是有问题的,因为代码在共享库中并且从MT应用程序使用。)< / p>

    有没有更好的方法在Solaris 10上使用套接字API检测最大允许缓冲区大小?

    有没有办法告诉Solaris的套接字API像其他系统那样截断值呢?

1 个答案:

答案 0 :(得分:2)

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

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

我不知道有一个C API,但是ndd使用的是什么?