首页 > 解决方案 > Why the restrictions on C standard I/O streams that interact with sockets?

问题描述

In book CSAPP section 10.9, it says that there are two restrictions on standard I/O streams that interact badly with restrictions on sockets.

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.

But I cannot figure out why the restrictions imposed. So, my question is: what factors result to the two restrictions?

It also says that "It is illegal to use the lseek function on a socket.", but how is it possible fseek, fsetpos and rewind use lseek to reset the current file position if it is true?

There is a similar question here, but my question different from this one.

标签: csocketsnetworkingioc-standard-library

解决方案


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

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

因此,从 C99 的基本原理

fsetpos只有在成功的 、fseekrewind或操作之后才允许更改更新文件的输入/输出方向 fflush,因为这些正是确保 I/O 缓冲区已被刷新的函数。

请注意,所有这些仅适用于打开的+文件 - 以任何其他标准模式打开的文件,不可能混合输入和输出。

由于 C 标准要求在函数, or上从输入切换到输出时,本质上调用必须成功(请注意,调用会导致写入缓冲的输出,并且肯定不会丢弃缓冲的输入)在尝试输出函数之前...但是套接字是不可搜索的,因此总是会失败- 这意味着您不能使用已为读写打开的套接字来实际读取写入套接字.FILE *fsetposrewindfseeklseekfflushlseekFILE *


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


推荐阅读