Я наткнулся на своеобразную разницу между сокетами Solaris 10 и другими сокетами Linux / * NIX. Пример:
int temp1, rc;
temp1 = 161024; /* 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
, указывающей на ошибку конфигурации.
После некоторого обсуждения было решено, что, поскольку конкретное приложение является критическим, а не дает сбой, оно должно продолжать работать как можно более изящно:
- В файле журнала выдается предупреждение о несоответствии конфигурации (просто, добавьте проверку с помощью
getsockopt()
) и
- Попробуйте установить максимальный размер буфера (чтобы получить максимально возможную производительность).
№ 2, где я застрял. Во всех системах, отличных от Solaris, мне не нужно ничего делать: сокеты уже делают это для меня.
Но на Солярисе я в недоумении, что делать. Я реализовал некоторую тривиальную дихотомию вокруг условия (setsockopt(...) == -1 && errno == ENOBUFS)
, чтобы найти максимальный размер буфера, но это выглядит ужасно. (Также у меня нет контекста для сохранения результатов поиска: поиск пришлось бы повторять для каждого соединения с такой плохой конфигурацией. Глобальные переменные проблематичны, поскольку код находится внутри разделяемой библиотеки и используется из приложения MT.)
Есть ли какой-нибудь лучший способ для определения максимально допустимого размера буфера в Solaris 10 с помощью API сокетов? *1024*
Есть ли какой-либо способ сообщить API сокетов Solaris обрезать значение, как это делают другие системы?