本文主要是介绍UNIX网络编程卷1:套接字联网-第3章:套接字编程-readn,writen函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
既然我们已经有了系统提供的接口read和write,为什么还需要readn writen 和readline呢?
因为字节流套接字上调用read或write输入和输出的字节数可能比请求的数量少,然而这不是出错状态(在我的另一篇博文:点击此处 已经指出),为了预防万一,不让实现返回一个不足的字节计数值,unix网络编程作者就封装了以下函数
在/unpv13e/lib 下unp.h中有如下申明
ssize_t readn(int, void *, size_t);
ssize_t writen(int, const void *, size_t);
在lib/下 vim readn.c
/* include readn */
#include "unp.h"ssize_t /* Read "n" bytes from a descriptor. */
readn(int fd, void *vptr, size_t n)
{size_t nleft;ssize_t nread;char *ptr; //我们人工的加了一层缓冲区,用于存read从fd处读到的指定字节ptr = vptr;nleft = n;while (nleft > 0) {//下面操作刚接触网络编程的人可能不太理解,read默认是阻塞函数,也就是说应用进程可能会阻塞到此处(如资源数据还没准备到位),对于阻塞函数,我们需要仔细分析每一种
//返回值情况,从而一一处理,read返回值的三种状态,正整数,0,,1,以后我会专门以源码出发的角度详解)if ( (nread = read(fd, ptr, nleft)) < 0) {if (errno == EINTR) /*表示此调用被信号中断*/nread = 0; /* and call read() again */ else return(-1); /*错误发生,返回-1,文件读写位置无法预期,只能返回-1(表示错误)退出 */} else if (nread == 0) /*读到文件尾部或者对端执行关闭操作*/
break; /* EOF */nleft -= nread;ptr += nread;}return(n - nleft); /* return >= 0 */
}/* end readn */
/*包裹函数*/
ssize_t
Readn(int fd, void *ptr, size_t nbytes)
{ssize_t n;if ( (n = readn(fd, ptr, nbytes)) < 0)err_sys("readn error");return(n);
}
//readn函数:从一个描述符读n字节
在lib/ 下 vim writen.c
/* include writen */ #include "unp.h"ssize_t /* Write "n" bytes to a descriptor. */ writen(int fd, const void *vptr, size_t n) {size_t nleft;ssize_t nwritten;const char *ptr;ptr = vptr;nleft = n;while (nleft > 0) {if ( (nwritten = write(fd, ptr, nleft)) <= 0) {if (nwritten < 0 && errno == EINTR) //被信号中断nwritten = 0; /* and call write() again */elsereturn(-1); /* error ,文件读写位置无法预期*/}nleft -= nwritten;ptr += nwritten;}return(n); } /* end writen *//*包裹函数*/ void Writen(int fd, void *ptr, size_t nbytes) {if (writen(fd, ptr, nbytes) != nbytes)err_sys("writen error"); }
这篇关于UNIX网络编程卷1:套接字联网-第3章:套接字编程-readn,writen函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!