使用xinetd / inetd,为什么服务器应该调用fflush()?

时间:2014-03-28 22:23:03

标签: fork fflush inetd xinetd

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 个答案:

答案 0 :(得分:0)

我认为你不需要在fclose之前调用fflush。在每个fputs之后我没有看到任何理由调用fflush。基本上,当您需要同步某些操作时,您只需要fflush,但在大多数情况下,有更好的方法可以执行此操作。除非你是一名数据库开发人员,否则IMO通常应该避免使用fflush。

如果删除fflush,程序也会正常工作,即将stdin转储到文件中,并在退出时关闭文件。

另外,我认为它与inetd或xinetd没有任何关系。

正如在另一个答案中写的那样,监视文件只会在刷新缓冲区时立即显示数据,但我认为在每次读取后刷新是一种糟糕的编程习惯。如果您想要立即获取数据,最好使用:

setvbuf(fp, NULL, _IONBF, 0)

但是,即使这还不够,因为stdin的缓冲是你的数据来源,但未指定AFAIK。您还需要设置它:

setvbuf(stdin, NULL, _IONBF, 0)

如果您想要精确控制读/写行为并且不针对非POSIX平台,我相信您应该始终更喜欢POSIX函数而不是ANSI函数。 POSIX open()read()write()的语义比fopen()fread()fwrite()的语义简单得多。它只是在一次系统调用中读取/写入尽可能多的数据,并且除了你自己的缓冲区和内核套接字缓冲区之外没有缓冲,只要你提出它就会提供数据。

答案 1 :(得分:0)

fopen使用缓冲输入。也就是说,调用fputs将写入内存缓冲区,而不必将数据写入磁盘。调用fflush会强制将输出缓冲区写入磁盘。

您的示例代码正在使用此模式,以便在通过套接字写入某些数据时立即写入文件,并且您可以监视该文件以了解所写的内容。