首页 > 代码库 > Linux非阻塞IO(三)非阻塞IO中缓冲区Buffer的实现
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 1024typedef 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的实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。