本文我们来实现回射服务器的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的实现的更多相关文章

  1. {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) 五 ...

  2. Java-五种线程池,四种拒绝策略,三种阻塞队列(转)

    Java-五种线程池,四种拒绝策略,三种阻塞队列 三种阻塞队列:    BlockingQueue<Runnable> workQueue = null;    workQueue = n ...

  3. linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

      IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...

  4. Linux IO模式-阻塞io、非阻塞io、多路复用io

    一 概念说明 在进行解释之前,首先要说明几个概念: - 用户空间和内核空间 - 进程切换 - 进程的阻塞 - 文件描述符 - 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对3 ...

  5. 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  6. Linux中同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  7. Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO

    背景 整理之前学习socket编程的时候复习到了多路复用,搜索了有关资料,了解到多路复用也有局限性,本着打破砂锅问到底的精神,最终找到了关于IO模型的知识点. 在<Unix网络编程>一书中 ...

  8. Linux IO 同步/异步 阻塞/非阻塞

    同步IO:导致请求进程阻塞,直到IO操作完成: 是内核通知我们何时进行启动IO操作,而实际的IO操作需要当前进程本身阻塞完成: 包括:阻塞式IO模型,非阻塞式IO模型,IO复用模型,信号驱动式IO模型 ...

  9. 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...

随机推荐

  1. 经典 Javascript 正则表达式

    正则表达式用于字符串处理,表单验证等场合,实用高效,但用到时总是不太把握,以致往往要上网查一番.我将一些常用的表达式收藏在这里,作备忘之用.匹配中文字符的正则表达式:  }

  2. linux c/c++ 代码使用 doxygen 自动生成文档

    www.doxygen.org 的使用非常方便,下面分成2步介绍一下 1. 注释风格,需要在c/c++代码中按照下面的风格添加注释,基本上还是很顺手的 C++的注释风格 主要使用下面这种样式:即在注释 ...

  3. c++ poco StreamSocket tcpclient测试用例

    1.代码 #include <iostream> #include "Poco/Net/Socket.h" #include "Poco/Net/Stream ...

  4. 为什么32位系统最大支持4G内存??我自己悟出来了 终于 。。。。。

    今天突然开窍了,想通了..... 以下是我的抽象想法: 32位系统 这个 多少位 指的是 硬件的 一次性发送过来的位数,一个字节 等于8位,内存的一个存储单元就是一个字节,即8位. 也可以这样来想这个 ...

  5. logrotate 学习使用

    logrotate Summary : Rotates, compresses, removes and mails system log files Description : The logrot ...

  6. 解决iOS10的Safari下Meta设置user-scalable=no无效的方法

    苹果为了提高Safari中网站的辅助功能,屏蔽了Meta下的user-scalable=no功能.所以在iOS10下面,就算加上user-scalable=no,Safari浏览器也能支持手动缩放. ...

  7. Doki Doki Literature Club

    Doki Doki Literature Club! is a visual novel developed by Team Salvato. The protagonist is invited b ...

  8. 第十二届北航程序设计竞赛决赛网络同步赛 B题 前前前世(数论推导 + DP)

    题目链接  2016 BUAA-Final Problem B 考虑一对可行的点$(x, y)$ 根据题意,设$x = ak + 1,y = bk + 1$ 又因为$x$是$y$的祖先的祖先的祖先,所 ...

  9. python实现无重复字符串的最长子串

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  10. web通信 长连接、长轮询

    http://www.cnblogs.com/hoojo/p/longPolling_comet_jquery_iframe_ajax.html