博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
readn、write、readline
阅读量:6828 次
发布时间:2019-06-26

本文共 3181 字,大约阅读时间需要 10 分钟。

字节流套接字上的read和write函数所表现的行为不同于通常的文件IO

字节流套接字上调用read或write输入或输出的字节数可能比请求的数量少,然而这不是出错的状态

这个现象的原因在于内核中用于套接字的缓冲区可能已经达到了极限

此时需要的是调用者再次调用read或write函数,以输入或输出剩余的字节

 

 

ssize_t readn(int fd, void *vptr, size_t n)

 

/* 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_tReadn(int fd, void *ptr, size_t nbytes){	ssize_t		n;	if ( (n = readn(fd, ptr, nbytes)) < 0)		err_sys("readn error");	return(n);}

 

 

ssize_t writen(int fd, const void *vptr, size_t n)

 

/* 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 */voidWriten(int fd, void *ptr, size_t nbytes){	if (writen(fd, ptr, nbytes) != nbytes)		err_sys("writen error");}

 

ssize_t readline(int fd, void *vptr, size_t maxlen)

 

/* include readline */#include	"unp.h"static int	read_cnt;static char	*read_ptr;static char	read_buf[MAXLINE];static ssize_tmy_read(int fd, char *ptr){	if (read_cnt <= 0) {again:		if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {			if (errno == EINTR)				goto again;			return(-1);		} else if (read_cnt == 0)			return(0);		read_ptr = read_buf;	}	read_cnt--;	*ptr = *read_ptr++;	return(1);}ssize_treadline(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_treadlinebuf(void **vptrptr){	if (read_cnt)		*vptrptr = read_ptr;	return(read_cnt);}/* end readline */ssize_tReadline(int fd, void *ptr, size_t maxlen){	ssize_t		n;	if ( (n = readline(fd, ptr, maxlen)) < 0)		err_sys("readline error");	return(n);}

内部函数my_read每次最多读MAXLINE个字符,然后每次返回一个字符

readline函数本身的唯一变化是用my_read调用取代read

readlinebuf这个新函数能够展露内部缓冲区的状态,便于调用者查看当前文本行之后是否收到了新的数据

 

套接字地址结构是每个网络程序的重要组成部分,我们分配它们,填写它们,把指向它们的指针传递给各个套接字函数

有时我们把指向这些结构之一的指针传递给一个套接字函数,并由该函数填写结构内容

我们以引用形式来传递这些结构

而起将结构的大小作为另外一个参数来传递

当一个套接字函数需要填写一个结构时,该结构的长度也以引用形式传递,这样它的值也可以被函数更改

我们把这样的参数称为值-结果参数

 

套接字地址结构是自定义的,因为它们总是以一个标识其中所含地址之协议簇的字段开头

支持长度可变套接字地址结构的较新实现在开头还包含一个长度字段

它含有整个结构的长度信息

 

在表达格式(我们平时书写的格式,ascii字符串)

和数值格式(存放在套接字地址结构中的格式)

之间转换IP地址的2个函数:inet_pton和inet_ntop

 

TCP套接字为应用进程提供一个字节流,它们没有记录标记。从TCP套接字read的返回值可能比我们请求的数量少,但是这不代表发生了错误。

 

转载于:https://www.cnblogs.com/ailx10/p/5348367.html

你可能感兴趣的文章
Linux 命令简介
查看>>
第三方模块的安装
查看>>
Terracotta中锁与性能的问题
查看>>
遇到Linux系统安装时窗口过大,按钮点不到,该怎么解决
查看>>
Xamarin开发Android笔记:TextView行间距设定
查看>>
js 判断输入是否为正整数
查看>>
git学习资料包
查看>>
CSS3
查看>>
myEclipse配置jdk1.7
查看>>
游戏服务器开发中的一点值得注意的地方
查看>>
创建租房网House脚本
查看>>
ES6中export , export default , import模块系统总结
查看>>
JavaScript获取后台C#变量以及后台方法
查看>>
通讯录
查看>>
NAT 穿透
查看>>
go之变量、指针、引用地址
查看>>
统计一下ie的一些问题(什么时候遇到什么时候更新)
查看>>
HT for Web中3D流动效果的实现与应用
查看>>
「收藏」一些有趣的图
查看>>
spring boot项目开发中遇到问题,持续更新
查看>>