为什么要限制与套接字交互的C标准I / O流?

时间:2018-10-17 08:03:13

标签: c sockets networking io c-standard-library

在CSAPP的第10.9节中,它说标准I / O流有两个限制,它们与套接字的限制不能很好地交互。

  

限制1:输入功能紧随输出功能。如果没有中间调用fflush,fseek,fsetpos或rewind,输入函数就不能跟随输出函数。 fflush函数清空与流关联的缓冲区。后三个函数使用Unix I / O lseek函数重置当前文件位置。

     

限制2:输出功能紧随输入功能。除非输入函数遇到文件结尾,否则输出函数不能跟随输入函数而不会介入fseek,fsetpos或rewind。

但是我不知道为什么要施加限制。所以,我的问题是:什么因素导致这两个限制?

它还说“在套接字上使用lseek函数是非法的。”,但是fseekfsetposrewind怎么可能使用lseek重置当前文件位置(如果为true)?

有一个类似的问题here,但我的问题与此不同。

2 个答案:

答案 0 :(得分:1)

stdio函数用于缓冲文件的输入和输出。套接字不是文件,而是套接字。它甚至没有文件位置,并且缓冲区要求与普通文件完全不同-套接字可以具有独立的输入和输出缓冲区,而stdio文件I / O不能!

问题在于,文件输入文件输出共享相同文件位置,并且操作系统可能具有(并且实际上会在Unix上具有),由于C中的缓冲,文件位置不同于文件位置。

因此,根据C99原理

  

仅在成功后才允许在更新文件上更改输入/输出方向   fsetposfseekrewindfflush操作,因为这些恰好是功能   这样可以确保已清空I / O缓冲区。

请注意,所有这一切仅适用于以+打开的文件-在以任何其他标准模式打开的文件中,无法混合输入和输出。

由于C标准要求在FILE *的功能之一fsetpos上从 input 切换到 output 实际上尝试调用rewind的1}}或fseek必须成功(请注意,调用lseek会刷新输出,而不是输入缓冲区!),然后才尝试输出函数...套接字是不可搜索的,因此fflush总是失败-这意味着您不能同时使用lseek打开和读写包装​​套接字的方式FILE * 读取写入到套接字。


如果确实需要,可以使用fdopen用流套接字打开FILE *:只需打开 2 个文件-一个"rb"作为输入和另一个"wb"用于输出。

答案 1 :(得分:0)

当它说“如果没有中间人对fflush,fseek,fsetpos或rewind的调用,输入函数就不能跟随输出函数”,这意味着如果您不这样做,则它可能无法按预期工作。但是他们主要是在谈论普通文件的输入/输出。

如果您有一个FILE *流连接到套接字,并且想在读写之间来回切换,我希望如果您从切换时调用fflush可以正常工作从写作到阅读。从阅读转换为书写时,我不希望有必要调用任何东西。

(处理文件时,必须致电fseek或其亲戚之一才能正确更新文件位置,但是流中没有要更新的文件位置。)