Используя xinetd/inetd, почему серверы должны вызывать fflush()?
Все программы в xinetd (которые я прочитал) вызывают fflush(). Зачем?
Например, Inetd-Wikipedia
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
const char *fn = argv[1];
FILE *fp = fopen(fn, "a+");
if(fp == NULL)
exit(EXIT_FAILURE);
char str[4096];
//inetd passes its information to us in stdin.
while(fgets(str, sizeof(str), stdin)) {
fputs(str, fp);
fflush(fp);
}
fclose(fp);
return 0;
}
2 ответа
fopen
использует буферизованный ввод. То есть это призвание fputs
запишет в буфер в памяти и не будет необходимости записывать данные на диск. призвание fflush
принудительно записывает выходной буфер на диск.
В вашем примере кода используется этот шаблон, поэтому файл будет записан, как только некоторые данные будут записаны через сокет, и вы сможете отслеживать файл, чтобы узнать, что было написано.
Я не думаю, что вам когда-либо нужно вызывать fflush как раз перед fclose. Я не вижу причин для вызова fflush после каждого fputs. По сути, fflush нужен только тогда, когда вам нужно синхронизировать некоторые действия, но в большинстве случаев есть лучшие способы сделать это. Вам следует избегать fflush в IMO, если вы не разработчик базы данных или что-то в этом роде.
Если вы удалите fflush, программа будет работать так же хорошо, то есть выгрузит stdin в файл и закроет файл при выходе.
Кроме того, я не думаю, что это имеет какое-либо отношение к inetd или xinetd.
Как написано в другом ответе, мониторинг файла будет показывать данные сразу, только если буферы сброшены, но я думаю, что это плохая практика программирования - сбрасывать после каждого чтения. Если вы хотите всегда получать данные немедленно, лучше использовать:
setvbuf(fp, NULL, _IONBF, 0)
Но даже этого недостаточно, поскольку буферизация stdin
источник ваших данных AFAIK не указан. Вам также нужно установить это:
setvbuf(stdin, NULL, _IONBF, 0)
Я считаю, что вы всегда должны отдавать предпочтение функциям POSIX, а не функциям ANSI, если вы хотите точно контролировать поведение чтения / записи и не ориентируетесь на платформы, отличные от POSIX. Семантика POSIX open()
, read()
а также write()
гораздо проще, чем один из fopen()
, fread()
а также fwrite()
, Он просто читает / записывает как можно больше данных за один системный вызов, и нет никакой буферизации, кроме вашего собственного буфера и буфера сокета ядра, который просто дает вам данные всякий раз, когда вы их запрашиваете.