Здесь много вопросов:
- Что именно указывает код возврата 0, и стоит ли тогда проверять errno или нужно просто сбросить соединение без дальнейшего изучения?
В системе POSIX send (2) никогда не сможет вернуть 0, если вы не вызовете его с аргументом длины 0. Проверьте документы для вашей конкретной системы, чтобы убедиться, что она соответствует спецификации POSIX
- Означает ли получение отрицательного возвращаемого значения гарантию закрытия испорченного соединения, или это только так, если только errno не является EWOULDBLOCK, EAGAIN или EINTR (... другие)?
Нет, возвращаемое значение -1 (единственно возможное отрицательное возвращаемое значение) просто означает, что данные не были отправлены.Вам нужно проверить errno, чтобы увидеть ПОЧЕМУ - смотрите страницу руководства send (2) для получения полного списка всех возможных значений errno и их значения
- Стоит ли проверять errno, когдавозвращаемое значение> 0?По-видимому, значение указывает количество данных, «отправленных» (в кавычках, потому что это действительно длинный процесс, верно), но поскольку сокет не является блокирующим, означает ли это, что можно сразу выполнить другой вызов или, в зависимости от errno снованужно ждать следующего события отправки (используя select / poll / epoll)?
Если send вернет успех (> 0), то errno не изменится и будет содержать все, что былоbefore (что, вероятно, является ошибкой из-за какого-то более раннего системного вызова).
- В основном, проверяется ли сначала возвращаемое значение, а затем только значение errno?Или, может быть, отправлять наборы errno при каждом вызове, независимо от возвращаемого значения?Это несколько упростит проверку ошибок ...
Сначала проверьте возвращаемое значение, а затем errno, если возвращаемое значение равно -1.Если вы действительно хотите, вы можете установить errno равным 0 перед вызовом, а затем проверить его потом
- Если вы получите EINTR, что будет хорошим, устойчивым поведением для программы?Просто запишите состояние и повторите попытку при следующей отправке, как в случае EWOULDBLOCK и EAGAIN?
Что ж, проще всего отключить прерывание системных вызовов, и в этом случае вы никогда не получитеEINTR.Обрабатывать его так же, как EWOULDBLOCK / EAGAIN, тоже хорошо.
- Проверяет ли EWOULDBLOCK и EAGAIN один?Можем ли мы доверять тому, что оба имеют одно и то же значение, или это зависит от реализации?
Зависит от реализации, хотя в целом они одинаковы.Иногда существуют странности с режимами эмуляции SysV и BSD, которые могут отличать их друг от друга и могут произойти либо
- Возвращает ли send EMSGSIZE для потоковых сокетов?Если этого не произойдет, то размер буфера не будет слишком большим, верно?
Потоковые сокеты не имеют атомарных сообщений, а EMSGSIZE предназначен только для атомарных сообщений, поэтому нет, потоковые сокеты могутне вернуть EMSGSIZE
- Может ли само возвращаемое значение быть равно одному из известных кодов ошибок?
Единственный код ошибки - -1.Успех - это количество записанных байтов, поэтому, если вы могли бы записать 2 ^ 32-1 байта на 32-битной машине (или 2 ^ 64-1 на 64-битной машине), это было бы проблемой, но вы не можетенапишите так много байтов (и вы, как правило, получите EINVAL или EFAULT).