Почему чтение неблокирующего сокета возвращает код ошибки - PullRequest
0 голосов
/ 03 июля 2019

После успешного чтения сокета, настроенного как неблокирующее, сокет становится временно недоступным.Все данные получены уже при первом вызове read, но возвращаемое значение ошибки сохраняется в течение 5 секунд.После этого read возвращает 0 и сокет снова становится доступным.

Почему сокет возвращает ошибку в первую очередь?

Настройка неблокирующего сокета:

/* Non blocking */
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

Прочитать сокет и напечатать:

result = read(sockfd, response + bytes_read, RESPONSE_SIZE - bytes_read);
printf("%d | %d | %s\n", (int)result, errno, strerror(errno));
printf("%d | %d | %d | %d | %d | %d | %d | %d \n",
            EAGAIN, EWOULDBLOCK, EBADF, EFAULT, EINTR, EINVAL, EIO, EISDIR);

Что приводит к:

152 | 115 | Operation now in progress
11 | 11 | 9 | 14 | 4 | 22 | 5 | 21 

-1 | 11 | Resource temporarily unavailable
11 | 11 | 9 | 14 | 4 | 22 | 5 | 21 

Ответы [ 2 ]

4 голосов
/ 03 июля 2019

Когда сокет настроен как неблокирующий, если нечего читать, функция read вернет -1 и установит errno либо EAGAIN, либо EWOULDBLOCK.Вот как вы знаете, что читать нечего, и в этот момент вы можете сделать другие вещи, прежде чем пытаться снова.

Если read возвращает 0, это означает, что был достигнут конец файла, или для сокета, которыйпроизошло отключение.

2 голосов
/ 03 июля 2019

Если в неблокирующем файле типа FIFO или типа сокета нет доступных данных, чтение завершится неудачно с -1 и для errno будет установлено значение EWOULDBLOCK.Псевдоним этого errno кода - EAGAIN, который сигнализирует о необходимости повторной попытки (позже, после ввода дополнительных данных).

Возвращаемое значение 0 из read в сокетеуказывает, что подразумевается условие конца файла (для сокета это означает, что произошло отключение).

Из чтения (2):

(ноль означает конецфайла)

...

При ошибке возвращается -1 и значение errno устанавливается соответствующим образом.

...