36.muduo学习笔记之net_Buffer.{h&cc}

1. 说明

  1. 一个Buffer类

  2. 非阻塞网络编程中应用层buffer是必须的,要让程序在write操作上不阻塞,网络库必须给每个tcp connection配置output buffer.

  3. 在TcpConnection中使用,有两个,分别是inputbuffer和outputbuffer,TcpConnection会从socket读取数据,然后写入inputbuffer,客户代码从inputbuffer读取数据.对于outputbuffer,客户代码会把数据写入outputbuffer,TcpConnection从outputbuffer读取数据并写入socket

  4. epoll使用LT模式的原因

    • 与poll兼容
    • LT模式不会发生漏掉事件的BUG,但POLLOUT事件不能一开始就关注,否则会出现busy loop,而应该在write无法完全写入内核缓冲区的时候才关注,将未写入内核缓冲区的数据添加到应用层output buffer,直到应用层output buffer写完,停止关注POLLOUT事件
    • 读写的时候不必等候EAGAIN,可以节省系统调用次数,降低延迟(注:如果用ET模式,读的时候读到EAGAIN,写的时候知道output buffer 写完或者EAGAIN)

2. 变量

1. 私有

  1. std::vector buffer_;

    • char数组
  2. size_t readerIndex_;

    • 读位置下标
  3. size_t writerIndex_;

    • 写位置下标
  4. static const char kCRLF[];

    • 就是存储’\r\n’

2. 公有

  1. static const size_t kCheapPrepend = 8;

    • 这个是数据前预留的空间,可以让程序以很低的代价在数据前添加几个字节,比如在前面加几个字节表示消息的长度
  2. static const size_t kInitialSize = 1024

    • buffer_初始化大小

3. 函数

1. 私有

  1. char* begin()

  2. const char* begin() const

    • 以上两个返回buffer_.begin()
  3. void makeSpace(size_t len)

    • 对空间的动态调整,如果读位置前面可用的空间+写位置后面可用的空间够用的话,把数据复制到开始,如果不够用的话,再在后面动态增加空间

2. 公有

  1. 构造

    • buffer_和读写位置的初始化
  2. void swap(Buffer& rhs)

    • 交换缓冲区
  3. size_t readableBytes() const

    • 可读的数据大小,写位置-读位置
  4. size_t writableBytes() const

    • 可写的空间大小,buffer_大小-写位置
  5. size_t prependableBytes() const

    • 返回readerIndex_,表示之前有多大的空间是空的
  6. const char* peek() const

    • 返回读位置的指针
  7. const char* findCRLF() const

    • 这个就是在读位置和写位置之间的数据中找’\r\n’换行,找到的话返回这个指针,没找到返回NULL
  8. const char* findCRLF(const char* start) const

    • 这个是从start位置开始查找
  9. const char* findEOL() const

    • 使用memechr()查找’\n’,这个是从读位置后面的readableBytes()个字符中找’\n’
  10. const char* findEOL(const char* start) const

    • 从start位置开始找,功能如上
  11. void retrieve(size_t len)

    • 就是取完数据后(在其他函数中实现,),这个只移动读指针
    • 如果读指针和写指针重叠,也就是数据取完了,就都置为初始位置.
  12. void retrieveUntil(const char* end)

    • 这个是参数为指针,把这个指针之前的数据读取完,移动读指针
  13. void retrieveInt64()

  14. void retrieveInt32()

  15. void retrieveInt16()

  16. void retrieveInt8()

    • 上面四个分别是取出8,4,2,1字节,retrieve*系列函数都比较简单,最好是自己看代码理解
  17. void retrieveAll()

    • 把读写下标置为初始位置
  18. string retrieveAllAsString()

  19. string retrieveAsString(size_t len)

    • 以上两个,是吧读取的数据转换成字符串返回,并调用retrieve移动读下标
  20. StringPiece toStringPiece() const

    • 把可读数据转换为StringPiece类型返回
  21. void append(const StringPiece& str)

  22. void append(const char* /*restrict*/ data, size_t len)

  23. void append(const void* /*restrict*/ data, size_t len)

    • 以上三个就是把数据添加到buffer_缓冲区
  24. void ensureWritableBytes(size_t len)

    • 就是确保缓冲区空间够写,动态增长空间
  25. char* beginWrite()

  26. const char* beginWrite() const

    • 上面两个返回写位置的指针
  27. void hasWritten(size_t len)

    • 移动写位置下标,+len
  28. void unwrite(size_t len)

    • 写位置下标-len
  29. void appendInt64(int64_t x)

  30. void appendInt32(int32_t x)

  31. void appendInt16(int16_t x)

  32. void appendInt8(int8_t x)

    • 以上四个把主机字节序的转换成网络字节序追加到缓冲区后面
  33. int64_t readInt64()

  34. int32_t readInt32()

  35. int16_t readInt16()

  36. int8_t readInt8()

    • 读取这些类型的数据返回,并移动读下标,代码比较好理解
  37. int64_t peekInt64() const

  38. int32_t peekInt32() const

  39. int16_t peekInt16() const

  40. int8_t peekInt8() const

    • 把可读缓冲区中相应字节大小的数据读出来返回
  41. void prependInt64(int64_t x)

  42. void prependInt32(int32_t x)

  43. void prependInt16(int16_t x)

  44. void prependInt8(int8_t x)

  45. void prepend(const void* /*restrict*/ data, size_t len)

    • 在可读数据前面增加一些数据
  46. void shrink(size_t reserve)

    • 缩小空间,使得空间为可读数据+reserve的大小
  47. size_t internalCapacity() const

    • 返回buffer_的capacity()
  48. ssize_t readFd(int fd, int* savedErrno);

    • 从套接字读取数据然后添加到缓冲区中,使用栈上的空间,避免内存使用过大,并且一次尽可能读取更多的数据
    • vec[2]为两块缓冲区,第一块指向写的位置,第二块指向栈上的缓冲区,如果第一块缓冲区足够容纳缓冲区数据,就直接返回了.否则才使用第二块缓冲区,即栈上的空间,在append()到缓冲区,这样就提高了内存使用效率,如果一开始就直接分配64k空间的话,可能用不到,就浪费空间了.
    • 这里使用了自己封装的readv,实际还是调用标准的readv(),这里的第三个参数是指明有多少块内存数据需要从fd读出.如果可写空间<64k的话,这里就填2,否则就填1.这里这个判断不咋理解,不明白为什么这样判断
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值