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 является лучшим выбором, если только вы не хотите получить ошибку непосредственно перед полной загрузкой данных.

Другие вопросы по тегам