C++流的streambuf详解及TCP流的实现
streambuf是C++流(iostream)与流实体(文件、标准输入输出等)交互的桥梁
# 文件流 fstream <--> filebuf <--> file # 字符串流 stringstream <--> stringbuf <--> string
上面的文件流和字符串流是C++标准库已经提供了的,现在我的目标是实现一个使用TCP协议通信的socket流
tstream <--> tcpbuf <--> socket(tcp)
首先来分析一下streambuf的内部实现
streambuf内部实现
术语说明:
- get 相当于 从流中读取数据
- put 相当于 写入数据到流中
- 字符,C/C++中的**char**,也可以理解为**字节**
streambuf内部持有三个用于get的指针gfirst,gnext,glast和三个用于put的指针pfirst,pnext,plast,这些指针分别可以使用eback(),gptr(),egptr()和pbase(),pptr(),epptr()函数获得,在代码中需要使用这些函数获取指针,为了方便描述,我直接使用这些指针变量名
下面是其他几个受保护的成员函数的作用
- gbump(n) : gnext+=n
- setg : setg(gfirst, gnext, glast)
- pbump(n) : pnext+=n
- setp : setp(pfirst, pnext, plast)
小结:
- get缓冲区通过setg()设置,setg的三个参数分别对应gfirst,gnext,glast
- put缓冲区通过setp()设置,setp的两个参数分别对应pfirst,plast
- 如果继承自streambuf的子类不通过setg和setp设置缓冲区,也就是**读写缓冲区为空**,那么这个流可以说是**不带读缓冲和写缓冲的流**,这时gfirst = gnext = glast = pfirst = pnext = plast = NULL
子类需要override(覆写)几个虚函数来封装具体的流的实现
虚函数(protected)
这些函数有些需要子类实现,来屏蔽不同的流的具体实现,向上提供统一的接口
缓冲区管理
- setbuf ---------- 设置缓冲区
- seekoff --------- 根据相对位置移动内部指针
- seekpos --------- 根据绝对位置移动内部指针
- sync ------------ 同步缓冲区数据(flush),默认什么都不做
- showmanyc ------- 流中可获取的字符数,默认返回0
输入函数(get)
- underflow(c) ---- 当get缓冲区不可用时调用,用于获取流中当前的字符,注意获取和读入的区别,获取并不使gnext++,默认返回EOF
- uflow ----------- 默认返回underflow(),并使gnext++
- xsgetn(s, n) ---- 从流中读取n个字符到缓冲区s中并返回读到的字符数:默认从当前缓冲区中读取n个字符,若当前缓冲区不可用,则调用一次uflow()
- pbackfail ------- 回写失败时调用
输出函数(put)
- xsputn(s, n) ---- 将缓冲区s的n个字符写入到流中并返回写入的字符数
- overflow(c) ----- 当put缓冲区不可用时调用,向流中写入一个字符;当c==EOF时,流写入结束
缓冲区不可用是指gnext(pnext) ==
NULL或者gnext(pnext) >= glast(plast)
阅读全文请点击:
http://click.aliyun.com/m/22232/
#C++工程师#