muduo buffer类的设计与使用
Unix/Linux上的五种IO模型(UNP6.2)
IO多路复用一般不能和blocking IO用在一起,因为blocking IO中read() write() accept() connect()都有可能阻塞当前线程,这样线程就没办法处理其他socket上的IO事件了
non-blocking IO的核心思想是避免阻塞在read()或write()或其他IO系统调用上,让一个线程能服务于多个socket连接,IO线程只能阻塞在IO多路复用函数上,如select、poll、epoll_wait,这样一来,应用层的缓冲是必须的.
1.TcpConnection必须要有output buffer:write系统调用可能一次不能发送完程序需要发送的数据,此时剩余的数据保存在output buffer中。要让程序在write操作上不阻塞,网络库必须要给每个TCP connection配置output buffer.
2.TcpConnection必须要有input buffer:收到的数据可能不构成一条完整的消息或者一次收到两条消息的数据,收到的数据先放到input buffer里,等构成一条完整的消息再通知程序的业务逻辑(TCP分包)
综上,muduo中的IO都是带缓冲的IO,不会自己去read()或write()某个socket,只会操作TcpConnection的input buffer和output buffer.
Muduo Buffer设计要点:
- 对外表现为一块连续的内存(char*, len),以方便客户代码的编写。
- 其 size() 可以自动增长,以适应不同大小的消息。它不是一个 fixed size array (即 char buf[8192]),通过vector自动实现
- 利用临时栈上空间,如果读入的数据不多,那么全部都读到 Buffer 中去了;如果长度超过 Buffer 的 writable 字节数,就会读到栈上的 stackbuf 里,然后程序再把 stackbuf 里的数据 append 到 Buffer 中。
Buffer的数据结构:

prependable空间,让程序能以很低的代价在数据前面添加几个字节.比方说,程序以固定的4个字节表示消息的长度,我要序列化一个消息,但是不知道它有多长,那么我可以一直 append() 直到序列化完成,然后再在序列化数据的前面添加消息的长度
Buffer的操作:
基本的read-write cycle:
iovec,与readv和wirtev操作相关的结构体,readv和writev函数用于在一次函数调用中读、写多个非连续缓冲区.
struct iovec{
void *iov_base; /* Pointer to data. */
size_t iov_len; /* Length of data. */
};
//写数据到缓冲区,writeIndex后移,从缓冲区中读数据,readIndex后移
ssize_t Buffer::readFd(int fd, int* savedErrno)
{
// saved an ioctl()/FIONREAD call to tell how much to read
char extrabuf[];
struct iovec vec[];
const size_t writable = writableBytes();
vec[].iov_base = begin()+writerIndex_;
vec[].iov_len = writable;
vec[].iov_base = extrabuf;
vec[].iov_len = sizeof extrabuf;
// when there is enough space in this buffer, don't read into extrabuf.
// when extrabuf is used, we read 128k-1 bytes at most.
const int iovcnt = (writable < sizeof extrabuf) ? : ;
const ssize_t n = sockets::readv(fd, vec, iovcnt);
if (n < )
{
*savedErrno = errno;
}
else if (implicit_cast<size_t>(n) <= writable)
{
writerIndex_ += n;
}
else
{
writerIndex_ = buffer_.size();
//将栈中的数据添加到buffer,如果buffer空间不够,需要扩容
append(extrabuf, n - writable);
}
// if (n == writable + sizeof extrabuf)
// {
// goto line_30;
// }
return n;
}
readv()将文件中连续的数据块读入内存分散的缓冲区中。writev()收集内存中分散的若干缓冲区中的数据写至文件的连续区域中。
#include <sys/uio.h>
ssize_t readv(int fildes, const struct iovec *iov, int iovcnt);
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt);
参数iovcnt指出数组iov的元素个数,元素个数至多不超过IOV_MAX,Linux中定义IOV_MAX的值为1024。
muduo buffer类的设计与使用的更多相关文章
- Buffer类的详解(转)
Buffer 类是 java.nio 的构造基础.一个 Buffer 对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里,数据可被存储并在之后用于检索.缓冲区可以被写满或释放.对于 ...
- Unity3D 游戏开发构架篇 ——角色类的设计与持久化
在游戏开发中,游戏角色占了很大的篇幅,可以说游戏中所有的内容都是由主角所带动.这里就介绍一下角色类的设计和持久化. 一.角色类应用场景和设计思想 游戏中的角色类型不一而足,有不同的技能,有不同的属性等 ...
- Node.js权威指南 (5) - 使用Buffer类处理二进制数据
5.1 创建Buffer对象 / 705.2 字符串的长度与缓存区的长度 / 725.3 Buffer对象与字符串对象之间的相互转换 / 74 5.3.1 Buffer对象的toString方法 / ...
- Node.js系列:Buffer类的使用
客户端JavaScript中没有对二进制数据提供很好的支持.但是在处理TCP流或文件流时,必须要处理二进制数据.Node.js定义了一个Buffer类,用来创建一个专门存放二进制数据的缓存区. Buf ...
- Node.js之使用Buffer类处理二进制数据
Node.js之使用Buffer类处理二进制数据 Buffer类可以在处理TCP流或文件流时处理二进制数据,该类用来创建一个专门存放二进制数据的缓存区. 1. 创建Buffer对象 1.1 直接创建: ...
- “乐”动人心--2017年10款最佳音乐类APP设计盘点
在上下班的路上,听几首自己喜欢的音乐来打发无聊的等公交车和地铁的时间是现代年轻人的常态.音乐作为最能鼓动人心的"语言",也成为了人们在互联网生活里占比例最高的消费活动之一,一款好看 ...
- 浅析nodejs的buffer类(转)
最近翻阅了node v0.10.4的buffer类的源代码,收获不少,也很久没有在cnode上发表文章了,想把一些收获分享给大家,有什么错误的地方希望大牛们指正啊. 前阵子有位rrestjs框架的使用 ...
- 关于FIFO memory buffer模块的设计
关于FIFO memory buffer模块的设计 FIFO memory `timescale 1ns / 1ps ///////////////////////////////////////// ...
- node.js—Buffer类(二进制数据处理模块)
Buffer类概述 一个用于更好的操作二进制数据的类 我们在操作文件或者网络数据的时候,其实操作的就是二进制数据流 Node为我们提供了一个更加方便的去操作这种数据流的类 Buffer,他是一个全局的 ...
随机推荐
- vue2.0 vue.set()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- HTML标签的分类
html中的标签元素大体被分为三种不同的类型:块状元素.内联元素和内联块状元素.常用的块状元素有:<div>.<p>.<h1>...<h6>.<o ...
- 未来IT行业的掌控者
(题外话,我发现很多高手都喜欢讲代码实现,喜欢贴代码贴图,我个人不大喜欢这种方式,我觉得最重要的是思想,是想法,具体的实现代码实现步骤由读者自己去实现.这纯属我个人喜好,望各大内高手勿喷,可能是本人水 ...
- iTOP-4412开发板-实战教程-ssh服务器移植到arm开发板
本文转自迅为开发板:http://www.topeetboard.com 在前面实战教程中,移植了“串口文件传输工具”,整个移植过程是比较简单的,而且我 们没有做任何协议方面的了解,只是“配置”+“编 ...
- Java HTTP 组件库选型看这篇就够了
最近项目需要使用 Java 重度调用 HTTP API 接口,于是想着封装一个团队公用的 HTTP client lib. 这个库需要支持以下特性: 连接池管理,包括连接创建和超时.空闲连接数控制.每 ...
- Java集合(二)--Iterator和Iterable
Iterable: public interface Iterable<T> { Iterator<T> iterator(); } 上面是Iterable源码,只有一个ite ...
- C# defult关键字
一.问题 今天写一个函数提示用defult,因为第一次用记录一下 public static T GetConfig<T>(string strConfig) { try { return ...
- js 上传图片、压缩、旋转
亲测 <!doctype html> <html> <head> <meta charset="utf-8"> <title& ...
- 查找BUG的方法
1)测试环境 1)代码调试 2)问题重现 3)思考问题所在 2)生产环境 1)思考 2)测试本地环境是否存在问题 3)打开日志查看 4)思考是否是数据原因 5)拷贝数据到本地进行重现 3)未知错误 1 ...
- 原生js上传图片
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...