**
文章目录
第16章 关于IO流分离的其他内容
:
什么是流?
调用fopen函数打开文件后,可以通过返回值 与文件进行数据交换。
因此说调用fopen函数后创建了流(stream)**
FILE *fopen(const char *path,const char *mode);
其中,path是我们要打开的流,而mode就是我们打开文件的方式了,也就决定你所打开的文件将被怎样的去对待啦,有如下几种方式:
"r":只读方式打开,打开的文件必须存在。
"r+" :读写方式打开,文件必须存在。
"w" : 只写方式打开,文件不存在则创建,文件存在则清空。
"w+" : 读写方式打开,文件不存在则创建,文件存在则清空。
"a" : 只写方式打开,追加的方式写到文件的尾部,文件不存在则创建。
"a+": 读写方式打开,文件不存在创建,从头开始读,从尾开始写。
此处的流是指数据流动,通常可以比喻为:以数据收发为目的的一种桥梁。
我们将流理解为数据收发路径
16.1 分离IO流
分离I/O流是一种参见表达。有I/O工具可以区分两者,无论使用什么方法都可以认为分离了I/O流。
16.1.1 两次IO流分离
先回顾一下:我们曾经使用过两种方法来分离I/O流。
第十章中的“TCP I/O过程分离”。
通过调用fork函数复制一个文件描述符,用来区分输入和输出种使用的文件描述符。虽然这种方法并非从本质上分开,而仅仅是我们通过子进程分开了两个文件描述符的用途,但这也是属于流的分离。
上一章:第十五章中使用2次fopen函数,创建读模式FILE指针和写模式FILE指针。
我们分离了输入工具和输出工具,因此也可以视为流的分离,下面说明分离的理由以及尚未说明的问题。
16.1.2 分离流的好处
上面说的两种流分离方式有所不同。
第十章的流分离目的:
通过分开输入过程(代码)和输出过程降低实现难度。
与输入无关的输出操作可以提高速度。
这些已经在第十章中讨论过了,具体可以去看第十章的内容
下面主要讨论一下使用系统函数的流分离过程。
第十五章流分离目的:
为了将FILE指针按照读模式和写模式加以区分
可以通过区分读写模式减低实现难度。
通过区分I/O缓冲提高缓冲性能。
流分离的方法、情况目的不同时,带来的好处也不同。
16.1.3 流分离带来的EOF问题
之前讲过调用shutdown
函数是基于半关闭的EOF传递方法
16.2 文件描述符的复制和半关闭
16.2.1 终止流时无法半关闭的原因
下图描述的是sep_serv.c示例中 2个FILE指针、文件描述符以及套接字之间的关系
上图什么意思呢?也就是说在上面的服务器端代码中(sep_serv.c)中的读模式FILE指针和写模式FILE指针都是用基于同一个文件描述符创建的。因此,针对任意一个FILE指针调用fclose函数时都会关闭文件描述符,也就代表着终止套接字。如下图所示
既然销毁了套接字无法在进行数据交换,那么如何进入可以输入(read)但是无法输出(write)的半关闭状态呢?
只需要在创建FILE指针前先复制文件描述符即可。
下面提供一个可行的模型方案:(半关闭模型1)