在书 CSAPP 第 10.9 节中,它说标准 I/O 流有两个限制,它们与套接字限制交互不良。
Restriction 1: Input functions following output functions. An input function cannot follow an output function without an intervening call to fflush, fseek, fsetpos, or rewind. The fflush function empties the buffer associated with a stream. The latter three functions use the Unix I/O lseek function to reset the current file position.
Restriction 2: Output functions following input functions. An output function cannot follow an input function without an intervening call to fseek, fsetpos, or rewind, unless the input function encounters an end-of-file.
但我不明白为什么要施加限制。那么,我的问题是:是什么因素导致了这两个限制?
它还说“在套接字上使用 lseek 函数是非法的。”,但是 fseek
、fsetpos
和 rewind< 怎么可能
使用 lseek
重置当前文件位置(如果为真)?
有个类似的问题here , 但我的问题与这个不同。
最佳答案
stdio
函数用于缓冲文件输入和输出。套接字不是文件,而是套接字。它甚至没有文件位置,缓冲区要求与普通文件截然不同——套接字可以有独立的输入和输出缓冲区,stdio 文件 I/O 不能!
问题是文件输入和文件输出共享相同文件位置,并且操作系统可能(并且确实会)在 Unix 上)有一个与 C 中缓冲的文件位置不同的文件位置。
因此,来自 C99 原理
A change of input/output direction on an update file is only allowed following a successful
fsetpos
,fseek
,rewind
, orfflush
operation, since these are precisely the functions which assure that the I/O buffer has been flushed.
请注意,所有这些仅适用于使用 +
打开的文件 - 对于以任何其他标准模式打开的文件,不可能混合输入和输出。
因为 C 标准要求在 FILE *
上从 input 切换到 output 时 fsetpos 函数之一
、rewind
或 fseek
,本质上调用 lseek
必须成功(请注意,调用 fflush
导致写入缓冲输出,并且肯定不会丢弃缓冲输入)在尝试输出函数之前...但是套接字不可搜索,因此 lseek
总是失败 - 这意味着您不能使用已打开的用于读取和写入的 FILE *
包装套接字,以用于实际上读取 和写入 em> socket 。
如果您确实需要,可以使用 fdopen
打开带有流套接字的 FILE *
:只需打开两个 文件 - 一个“rb”
用于输入,另一个 用于输出 “wb”
。
关于c - 为什么要限制与套接字交互的 C 标准 I/O 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52850028/