UNIX 网络编程学习(7)--readn,writen,readline的实现

原创 2012年03月23日 12:25:37

readn函数:

//lib/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;

	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		if ( (nread = read(fd, ptr, nleft)) < 0) {
			if (errno == EINTR)
				nread = 0;		/* and call read() again */
			else
				return(-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);
}

writen函数:

//lib/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 */
			else
				return(-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");
}

readline函数:

lib/readline.c

//效率提高了,比每次调用read读一个字节效率要高。
/* include readline */
#include	"unp.h"

static int	read_cnt;//刚开始可以置为一个负值(我的理解)
static char	*read_ptr;
static char	read_buf[MAXLINE];

static ssize_t
my_read(int fd, char *ptr)//每次最多读取MAXLINE个字符,调用一次,每次只返回一个字符
{

	if (read_cnt <= 0) {
again:
		if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {//如果读取成功,返回read_cnt=读取的字符			if (errno == EINTR)
				goto again;
			return(-1);
		} else if (read_cnt == 0)
			return(0);
		read_ptr = read_buf;
	}

	read_cnt--;//每次递减1,直到<0读完,才执行上面if的命令。
	*ptr = *read_ptr++;//每次读取一个字符,转移一个字符
	return(1);
}

ssize_t
readline(int fd, void *vptr, size_t maxlen)
{
	ssize_t	n, rc;
	char	c, *ptr;

	ptr = vptr;
	for (n = 1; n < maxlen; n++) {
		if ( (rc = my_read(fd, &c)) == 1) {
			*ptr++ = c;
			if (c == '\n')
				break;	/* newline is stored, like fgets() */
		} else if (rc == 0) {
			*ptr = 0;
			return(n - 1);	/* EOF, n - 1 bytes were read */
		} else
			return(-1);		/* error, errno set by read() */
	}

	*ptr = 0;	/* null terminate like fgets() */
	return(n);
}

ssize_t
readlinebuf(void **vptrptr)
{
	if (read_cnt)
		*vptrptr = read_ptr;
	return(read_cnt);
}
/* end readline */

ssize_t
Readline(int fd, void *ptr, size_t maxlen)
{
	ssize_t		n;

	if ( (n = readline(fd, ptr, maxlen)) < 0)
		err_sys("readline error");
	return(n);
}




 

相关文章推荐

unix中readn()与readline 的作用,,write,,read,,readn

read(int fd,void *buf,size_t  n),write(int fd,void *buf,size_t  n). 是系统自己实现的库函数。。 readn(int fd,void ...
  • sun_z_x
  • sun_z_x
  • 2014年03月21日 21:32
  • 976

Unix网络编程之readline函数

1.为什么要使用readline函数?首先我们先考虑一下网络字节流传递消息的时候的黏包问题,我们之前的解决办法是将存放消息的buf定义成一个结构体,里面有一个len成员用来记录下一次我要发送多少个字节...

Unix/Linux中的read和write函数

文件描述符   对于内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读或写一个文件时,使用open或cr...

unp中my_read和readline

my_read每次读取MAXLINE个字符,然后每次返回一个字符 用my_read先读取MAXLINE个字符,存储在数组里面,然后再用readline从数组里面一个一个字符读取 my_read只调用了...
  • onesafe
  • onesafe
  • 2013年10月31日 13:10
  • 878

readn,writen,readline函数

字节流套接字上的read和write函数所表现的行为不同于通常的文件I/O。字节流套接字上调用的read和write输入或输出的字节数可能比请求的数量少,然而这不是出错的状态,这个现象的原因在于内核中...

unp中my_read和readline

my_read每次读取MAXLINE个字符,然后每次返回一个字符 用my_read先读取MAXLINE个字符,存储在数组里面,然后再用readline从数组里面一个一个字符读取 my_read只调用了...
  • onesafe
  • onesafe
  • 2013年10月31日 13:10
  • 878

iOS开发-带你深入了解Runloop

带你深入了解Runloop
  • Cehae
  • Cehae
  • 2016年10月10日 01:23
  • 522

unix网络编程readn,writen,readline包裹函数

一、Readn包裹函数 /* include readn */ #include "unp.h" ssize_t /* Read "n" bytes from a descriptor. */ rea...

UNIX网络编程卷1:套接字联网-第3章:套接字编程-readn,writen函数

既然我们已经有了系统提供的接口read和write,为什么还需要readn writen 和readline呢?  因为字节流套接字上调用read或write输入和输出的字节数可能比请求的数量少,然...

linux网络编程之socket(六):利用recv和readn函数实现readline函数

在前面的文章中,我们为了避免粘包问题,实现了一个readn函数读取固定字节的数据。如果应用层协议的各字段长度固定,用readn来读是非常方便的。例如设计一种客户端上传文件的协议,规定前12字节表示文件...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UNIX 网络编程学习(7)--readn,writen,readline的实现
举报原因:
原因补充:

(最多只允许输入30个字)