Linux非阻塞IO(三)非阻塞IO中缓冲区Buffer的实现
本文我们来实现回射服务器的Buffer。
Buffer的实现
上节提到了非阻塞IO必须具备Buffer。再次将Buffer的设计描述一下:
这里必须补充一点,writeIndex指向空闲空间的第一个位置。
这里有三个重要的不变式:
1. 0 <= readIndex <= writeIndex <= BUFFER_SIZE
2. writeIndex – readIndex 为可以从buffer读取的字节数
3. BUFFER_SIZE – writeIndex 为buffer还可以继续读取的字节数
还有一点,数据读取完毕之后,要重置下标为0
根据我设计的这个示意图,我利用结构体封装了一个Buffer,如下:
#ifndef BUFFER_H_
#define BUFFER_H_ #include <poll.h> #define BUFFER_SIZE 1024 typedef struct {
char buf_[BUFFER_SIZE];
int readIndex_; //读取数据
int writeIndex_; //写入数据
} buffer_t; void buffer_init(buffer_t *bt);
int buffer_is_readable(buffer_t *bt);
int buffer_is_writeable(buffer_t *bt);
int buffer_read(buffer_t *bt, int sockfd);
int buffer_write(buffer_t *bt, int sockfd); #define kReadEvent (POLLIN | POLLPRI)
#define kWriteEvent (POLLOUT | POLLWRBAND) #endif //BUFFER_H_
这里的buffer先采用固定长度,后期可以改为动态数组。
下面我们来实现Buffer的每个函数。
第一个是初始化,内存清零,下标都设置为0即可。
void buffer_init(buffer_t *bt)
{
memset(bt->buf_, 0, sizeof(bt->buf_));
bt->readIndex_ = 0;
bt->writeIndex_ = 0;
}
缓冲区是否可以读出数据,需要判断(writeIndex – readIndex)是否大于0
int buffer_is_readable(buffer_t *bt)
{
return bt->writeIndex_ > bt->readIndex_;
}
缓冲区是否可写,需要判断是否有空闲空间。
int buffer_is_writeable(buffer_t *bt)
{
return BUFFER_SIZE > bt->writeIndex_;
}
接下来是调用read函数,buffer从fd中读取数据,read的最后一个参数为buffer的剩余空间。
int buffer_read(buffer_t *bt, int sockfd)
{
int nread = read(sockfd, &bt->buf_[bt->writeIndex_], BUFFER_SIZE - bt->writeIndex_);
if(nread == -1)
{
if(errno != EWOULDBLOCK)
ERR_EXIT("read fd error");
return -1;
}
else
{
bt->writeIndex_ += nread;
return nread;
}
}
最后是输出操作,将buffer中的数据写入sockfd,write的最后一个参数为buffer现存的字节数。
int buffer_write(buffer_t *bt, int sockfd)
{
int nwriten = write(sockfd, &bt->buf_[bt->readIndex_], bt->writeIndex_ - bt->readIndex_);
if(nwriten == -1)
{
if(errno != EWOULDBLOCK)
ERR_EXIT("write fd error");
return -1;
}
else
{
bt->readIndex_ += nwriten;
if(bt->readIndex_ == bt->writeIndex_)
{
bt->readIndex_ = bt->writeIndex_ = 0;
}
return nwriten;
}
}
Buffer的实现完毕。
下文开始编写回射服务器的客户端。
Linux非阻塞IO(三)非阻塞IO中缓冲区Buffer的实现的更多相关文章
- {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块
python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...
- Java-五种线程池,四种拒绝策略,三种阻塞队列(转)
Java-五种线程池,四种拒绝策略,三种阻塞队列 三种阻塞队列: BlockingQueue<Runnable> workQueue = null; workQueue = n ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- Linux IO模式-阻塞io、非阻塞io、多路复用io
一 概念说明 在进行解释之前,首先要说明几个概念: - 用户空间和内核空间 - 进程切换 - 进程的阻塞 - 文件描述符 - 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对3 ...
- 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型
1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...
- Linux中同步与异步、阻塞与非阻塞概念以及五种IO模型
1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...
- Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO
背景 整理之前学习socket编程的时候复习到了多路复用,搜索了有关资料,了解到多路复用也有局限性,本着打破砂锅问到底的精神,最终找到了关于IO模型的知识点. 在<Unix网络编程>一书中 ...
- Linux IO 同步/异步 阻塞/非阻塞
同步IO:导致请求进程阻塞,直到IO操作完成: 是内核通知我们何时进行启动IO操作,而实际的IO操作需要当前进程本身阻塞完成: 包括:阻塞式IO模型,非阻塞式IO模型,IO复用模型,信号驱动式IO模型 ...
- 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
随机推荐
- 百度之星初赛(A)——T5
今夕何夕 Problem Description 今天是2017年8月6日,农历闰六月十五. 小度独自凭栏,望着一轮圆月,发出了“今夕何夕,见此良人”的寂寞感慨. 为了排遣郁结,它决定思考一个数学问题 ...
- 求LCA最近公共祖先的离线Tarjan算法_C++
这个Tarjan算法是求LCA的算法,不是那个强连通图的 它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数 它的优点是比在线算法好写很多 不过有些题目是强制在线的,此类离线算法 ...
- UVA 10985 Rings'n'Ropes
最短路 参考了Staingger的博客 感觉DP的状态记录还是有毛病.可以DFS寻找结果也. #include <map> #include <set> #include &l ...
- c# GDI画图 双缓冲画图分析
双缓冲绘图分析 1.Windows 绘图原理 我们在 Windows 环境下看到各种元素,如菜单.按钮.窗口.图像,从根本上说,都是“画”出来的.这时的屏幕,就相当于一块黑板,而 Windows ...
- Delphi栈对象
来自:http://blog.csdn.net/iseekcode/article/details/5158985 ------------------------------------------ ...
- linux nbd & qemu-nbd
网络块设备: Network Block Device 可以将一个远程主机的磁盘空间,当作一个块设备来使用.就像一块硬盘一样. 使用它,你可以很方便的将另一台服务器的硬盘空间,增加到本地服务器上 ...
- 在Ubuntu/Centos使用 Let's Encrypt 证书部署 HTTPS的方法
certbot地址 apache服务器(ubuntu环境): 1.获取软件包: $ sudo apt-get update $ sudo apt-get install software-proper ...
- HDU 2586.How far away ?-在线LCA(ST)-代码很认真的写了注释(捞到变形)
2018.9.10 0:40 重新敲一遍,然后很认真的写了注释,方便自己和队友看,刚过去的一天的下午打网络赛有一题用到了这个,但是没写注释,队友改板子有点伤,因为我没注释... 以后写博客,代码要写注 ...
- Codeforces 938D Buy a Ticket (转化建图 + 最短路)
题目链接 Buy a Ticket 题意 给定一个无向图.对于每个$i$ $\in$ $[1, n]$, 求$min\left\{2d(i,j) + a_{j}\right\}$ 建立超级源点$ ...
- Spring Cloud 微服务架构解决方案
1 理解微服务 1.1 软件架构演进 软件架构的发展经历了从单体结构.垂直架构.SOA架构到微服务架构的过程. 1.1.1 单体架构 特点: 1.所有的功能集成在一个项目工程中. 2.所有的功能打一个 ...