UNP中引入readn的目的,以及socket下read的特点。

UNP中第72~73页中将read函数封装为了readn与readline函数。

readn用于读取n个字节到vptr中,readline用于读取一行数据到vptr中。

为什么要将read函数封装为readn与readline呢?

这是因为在文件类型为socket文件时,使用read和write进行I/O操作将会遇到缓冲区问题。

网络编程下,套接字中引入了缓冲区,以read为例,某个socket文件sockfd将维护两个缓冲区,一个为接收缓冲区,另一个为发送缓冲区。

接收缓冲区用于存储从对端发送来的数据,我们使用read从sockfd中读取数据到内存中vptr指向的区域时,就是从接收缓冲区往vptr中读入(read函数每次读,都会令sockfd的指针自动往后移动这次所读取的字节数,这样下次调用read就跟着上次read的尾处开始接着读)。因为socket文件引入了缓冲区,缓冲区的大小是有限制的,如果说目前的接收缓冲区已经快满了,sockfd维护的指针离接收缓冲区满不足n个字节,而此时我们又调用了read,希望从sockfd中读取n个字节到vptr中,此时只能读取不满n个字节,则read函数将返回一个正整数值x,而这个值不满n,即x代表只读取了只读取了x个字节。下次在调用 read时,会阻塞在此处,一直等到接收缓冲区清空,并且接收缓冲区内有数据可读后,被唤醒,进行read操作。

因此,将read封装为readn,在readn中一定保证返回的时候已经读取了n个字节。用nleft维护所剩余的未读的字节数量,当出现上述情况,某次只读了x个字节时,下次while将阻塞在read处,等到唤醒后试着读取n-x个字节,这样只要调用readn,则一定只会返回n或者不足n(这个不足n是读取到文件末尾的情况)。

posted @ 2019-06-18 23:07  李湘沅  阅读(470)  评论(0编辑  收藏  举报