SO_ERROR против errno
Для получения сокета системного вызова (как recv
) ошибка, что лучше (на уровне производительности)?
- Используйте старый добрый
errno
- Или использовать
SO_ERROR
какgetsockopt()
optname?
Я думаю errno
(определено для __error()
в моей системе) быстрее, потому что это не системный вызов. Я прав?
Преимущества SO_ERROR: автоматический сброс ошибок после получения, и мы уверены, что ошибка касается только нашего сокета. Это безопаснее.
Какой из них вы считаете лучше? Есть ли действительно разница в производительности между двумя?
2 ответа
Цитирую Дана Бернштейна:
Ситуация: Вы устанавливаете неблокирующий сокет и выполняете connect(), который возвращает -1/EINPROGRESS или -1/EWOULDBLOCK. Вы выбираете () сокет для записи. Это возвращается, как только соединение успешно или неудачно. (Исключение: в некоторых старых версиях Ultrix функция select() не заметит сбой до истечения 75-секундного таймаута.)
Вопрос: Что вы делаете после того, как select() возвращает возможность записи? Не удалось установить соединение? Если так, как это потерпело неудачу?
Если соединение не удалось, причина скрыта внутри сокета внутри so_error. Современные системы позволяют вам видеть so_error с getsockopt(,,SO_ERROR,,) ...
Он продолжает обсуждать тот факт, что getsockopt(,,SO_ERROR,,)
это современное изобретение, которое не работает на старых системах, и как получить код ошибки в таких системах. Но вам, вероятно, не нужно беспокоиться об этом, если вы программируете для системы Unix/Linux, выпущенной за последние 15 лет.
Справочная страница по Linux для connect
описывает то же использование SO_ERROR
,
Итак, если вы выполняете асинхронные операции с сокетами, вам может понадобиться SO_ERROR
, В любом другом случае просто используйте errno
,
Цитирование сетевого программирования Unix:
Если so_error отличен от нуля, когда процесс вызывает read, и нет данных для возврата, read возвращает –1 с errno, равным значению so_error (стр. 516 из TCPv2). Значение so_error затем сбрасывается на 0. Если для сокета имеются данные, поставленные в очередь, эти данные возвращаются чтением вместо состояния ошибки. Если so_error отличен от нуля, когда процесс вызывает запись, то возвращается -1 с errno, равным значению so_error (стр. 495 из TCPv2), а so_error сбрасывается в 0.
Таким образом, errno является лучшим выбором, если только вы не хотите получить ошибку непосредственно перед полной загрузкой данных.