Я читаю CSAPP в последнее время. В разделе 10.9 говорится, что стандартный ввод-вывод не следует использовать с сокетом по следующим причинам:
(1) Ограничения стандартного ввода/вывода
Ограничение 1: Функции ввода следуют за функциями вывода. Функция ввода не может следовать за функцией вывода без промежуточного вызова fflush, fseek, fsetpos или перемотки назад. Функция fflush очищает буфер, связанный с потоком. Последние три функции используют функцию Unix I/O lseek для сброса текущей позиции в файле.
Ограничение 2: Функции вывода следуют за функциями ввода. Выходная функция не может следовать за входной функцией без промежуточного вызова fseek, fsetpos или перемотки, если входная функция не встречает конец файла.
(2) Использование функции lseek для сокета является незаконным.
Вопрос 1. Что произойдет, если я нарушу ограничение? Я написал фрагмент кода, и он отлично работает.
Вопрос 2. Чтобы обойти ограничение 2, можно использовать следующий подход:
File *fpin, *fpout;
fpin = fdopen(sockfd, "r");
fpout = fdopen(sockfd, "w");
/* Some Work Here */
fclose(fpin);
fclose(fpout);
В учебнике было сказано,
Закрытие уже закрытого дескриптора в многопоточной программе — прямой путь к катастрофе.
Почему?