readn、write、readline

字节流套接字上的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_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);
}

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 */

void
Writen(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_t
my_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_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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

时间: 2024-10-05 20:36:59

readn、write、readline的相关文章

0723------Linux基础----------文件 IO 之 read 和 write (readn 、writen、readline)

1. readn 和 writen 1.1 基础巩固: read 和 write 函数的返回值 1.1.1 read 函数原型为:ssize_t  read(int fd, void* buf, size_t count); (这里的 void *在标准 C 中表示通用指针即任意类型的指针都可以对它赋值,ssize_t 是有符号整数)它的返回值如下: a)成功返回读取的字节数,这里可能等于 count 或者小于 count (当 count > 文件 size 的时候,返回实际读到的字节数):

2、C#面向对象:封装、继承、多态、String、集合、文件(上)

面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. 打包,便于管理,为了解决大型项目的维护与管理. 三.什么是类? 将相同的属性和相同方法的对象进行封装,抽象出 “类”,用来确定对象具有的属性和方法. 类.对象关系:人是类,张三是人类的对象. 类是抽象的,对象是具体的.对象可以叫做类的实例,类是不站内存的,对象才占内存. 字段是类的状态,方法是类执

Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

转载请注明出处:http://blog.csdn.net/anxpp/article/details/51512200,谢谢! 本文会从传统的BIO到NIO再到AIO自浅至深介绍,并附上完整的代码讲解. 下面代码中会使用这样一个例子:客户端发送一段算式的字符串到服务器,服务器计算后返回结果到客户端. 代码的所有说明,都直接作为注释,嵌入到代码中,看代码时就能更容易理解,代码中会用到一个计算结果的工具类,见文章代码部分. 相关的基础知识文章推荐: Linux 网络 I/O 模型简介(图文) Jav

java中常用的包、类、以及包中常用的类、方法、属性-----io包

由于最近有需要,所以下面是我整理的在开发中常用的包.类.以及包中常用的类.方法.属性:有需要的看看 java中常用的包.类.以及包中常用的类.方法.属性 常用的包 java.io.*; java.util.*; java.lang.*; java.math.*; java.sql.*; java.text.*; java.awt.*; javax.swing.*;   包名 接口 类 方法 属性 java.io.*; java.io.Serializable实现序列化 java.io.Buffe

python16_day02【列表、字典、集合】

1.列表 1 names = ['Alex',"Tenglan",'Eric'] 2 3 >>> names[0] 4 'Alex' 5 >>> names[2] 6 'Eric' 7 >>> names[-1] 8 'Eric' 9 >>> names[-2] #还可以倒着取 10 'Tenglan' 11 12 >>> names = ["Alex","Tengl

[转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委托是一个类型,是一个函数指针类型,这个类型将该委托的实例化对象所能指向的函数的细节封装起来了,即规定了所能指向的函数的签名,也就是限制了所能指向的函数的参数和返回值.当实例化委托的时候,委托对象会指向某一个匹配的函数,实质就是将函数的地址赋值给了该委托的对象,然后就可以通过该委托对象来调用所指向的函

2016年11月28日--ADO.Net 查、插、删、改 小练习

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.SqlClient; namespace ConsoleApplication1 { class Program { /// <summary> /// 执行TSQL语句 /// </summary> /// <

1、C#基础:变量、运算符、分支、循环、枚举、数组、方法

C#..Net以及IDE简介 一.什么是.Net? .Net指 .Net Framework框架,一种平台,一种技术. .Net Framework框架是.Net平台不可缺少的一部分,它提供了一个稳定的运行环境来保证我们基于.Net平台开发的各种应用能够正常运转. .Net Framework 各版本区别 2002年 1.0------vs2002 统一类型系统,基础类库,垃圾回收,多语言支持.ado.net 1.0.asp.net 1.0.winform 1.0. 2003年 1.1-----

Tomcat、Weblogic、JBoss、GlassFish、Resin、Websphere弱口令及拿webshell方法总结 [复制链接]

1.java应用服务器    Java应用服务器主要为应用程序提供运行环境,为组件提供服务.Java 的应用服务器很多,从功能上分为两类:JSP 服务器和 Java EE 服务器.1.1  常见的Server概述    常见的Java服务器:Tomcat.Weblogic.JBoss.GlassFish.Jetty.Resin.IBM Websphere.Bejy Tiger.Geronimo.Jonas.Jrun.Orion.TongWeb.BES Application Server.Col

【笔试】7、统计出其中英文字母、空格、数字和其它字符的个数

/** * 题目:题目:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. * 时间:2015年7月28日10:04:33 * 文件:lianxi07.java * 作者:cutter_point */ package bishi.zuixin50.t2015728; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutp