muduo源码分析之Buffer设计

好久没有看muduo了,最近看Nginx看的有点醉,换换口味。


(一)阻塞与非阻塞I/O总结

1、对于read 调用,如果接收缓冲区中有 20字节,请求读 100个字节,就会返回 20;对于 write调用,如果请求写 100个字节,而发送缓冲区中只有 20个字节的空闲位置,那么 write会阻塞,直到把 100个字节全部交给发送缓冲区才返回。

对于非阻塞I/O来说,以write为例,假设要保证将应用程序的100个字节全部发送,这个时候write了20个字节的数据之后,由于发送缓冲区满,write返回一个EAGAIN的错误,为了保证能够将数据全部发送,需要写一个循环:

int n = strlen(buffer);//n : 100 bytes
while (n > 0) {
    nwrite = write(fd, buf + data_size - n, n);
    if (nwrite < n) {
  //未全部发送
        if (nwrite == -1 && errno != EAGAIN) {
            perror("write error");
        }
        break;
    }
    n -= nwrite;//剩余待发送
}

2、read 没有一点数据可读或 write 没有一点空间可以写入,如果disable O_NONBLOCK 则会阻塞。如果enable O_NONBLOCK 则会返回-1,errno = EAGAIN | EWOULDBLOCK 错误。(这是阻塞与非阻塞I/O最直观的说明)

3、阻塞模式下可以用setsockopt设置SO_RCVTIMEO(超时时间),即如果在超时时间内接收缓冲区都没有一点数据到来,那么返回-1,errno = EAGAIN | EWOULDBLOCK 错误。

同理,还有SO_SNDTIMEO 选项,在超时时间内发送缓冲区都没有足够内存存放数据,也是返回-1,errno = EAGAIN | EWOULDBLOCK 错误。

4、recv的第四个参数若为MSG_WAITALL,则在阻塞模式下不等到指定数目的数据不会返回,除非超时时间到。当然如果对方关闭了,即使超时时间未到,recv 也返回0。/usr/include/i386-linux-gnu/bits/socket.h MSG_WAITALL = 0x100

5、在多线程环境中,某个线程的阻塞不会引起进程的阻塞,除非进程中的所有线程都被阻塞。(pthread)


(二)muduo::Buffer简介

在上述I/O中,进程直接跟套接字打交道,muduo对I/O做了一层封装,让网络库与真正的套接字打交道,在应用层只需要利用封装的Buffer完成数据的收发,下面简要介绍其实现。

对于一个TcpConnection来说,在应有层对Buffer的封装有两个方面。

1.TcpConnection必须要有output buffer
2.TcpConnection必须要有input buffer

2.1Output Buffer简介

假设现在套接字可写(发送缓冲未满),poll/epoll/selectPOLLOUT事件激活,应用程序想要通过TCP连接发送100KB数据,但是现在发送缓冲区只有80KB空闲࿰

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值