Day2: 内存管理中的读写缓冲区

1 读写缓冲区reactor_buf

1.1 属性

        io_buf* _buf

1.2 方法

        length():获取_buf未读处理数据的长度

        pop(int len):弹出已处理输出(len为已处理数据长度)

        clear():清空_buf并将_buf放回buf_pool内存池中

class reactor_buf{
public: 
    reactor_buf(); //构造函数声明
    ~reactor_buf();  //析构函数声明

    //得到当前的buf还有多少有效数据
    int length();

    //已经处理了多少数据
    void pop(int len);

    //当前buf清空
    void clear();

protected:
    io_buf* _buf;
};

2 网络通信中读取数据缓冲区input_buf

        int read_data(int fd):将fd读取至io_buf中

        const char *data():获取缓冲区中的数据

        void adjust():读取完后重置缓冲区

class input_buf: public reactor_buf{ //input_buf继承reactor_buf
public:
    //从一个fd中读取数据到reactor_buf中
    int read_data(int fd);

    //获取当前的数据的方法
    const char *data();

    //重置缓冲区
    void adjust();
};

//从一个fd中读取数据到reactor_buf中
int input_buf::read_data(int fd)
{
    int need_read; //有多少数据待读取
    //一次性将io中的缓存数据全部读出来
    //传一个参数,目前缓存中一共有多少数据是可读

    if(_buf==NULL)
    {
        //如果input_buf里的_buf是空,需要从buf_pool中重新获取
        _buf = buf_pool::instance()->alloc_buf(need_read);
        if(_buf==NULL){
            fprintf(stderr, "no buf for alloc\n");
            return -1;
        }
    }else{
        //如果_buf可用,判断当前buf时候够存
        assert(_buf->head==0);
        if(_buf->capacity-_buf->length < need_read)
        {
            //当前情况不够村,需要重新申请一个buf
            io_buf *new_buf = buf_pool::instance()->alloc_buf(need_read+_buf->length);
            //将之前的_buf数据拷贝到新的buf中
            new_buf->copy(_buf);
            //将之前的_buf放回pool
            buf_pool::instance()->revert(_buf);
            //新申请的buf为当前的io_buf
            _buf = new_buf;
        }
    }

    int already_read = 0; //
    //此时,当前buf空间足够,可以开始读取数据
    do{
        if(need_read==0)
            already_read = read(fd, _buf->data+_buf->length, m4k); //阻塞直到有数据
        else
            already_read = read(fd, _buf->data+_buf->length, need_read);
    }while(already_read==-1&&errno==EINTR);

    if(already_read>0)
    {
        if(need_read!=0)
            assert(already_read==need_read);
        _buf->length += already_read; //如成功读取数据,更新缓冲区长度
    }
    return already_read; //返回读取字节数
}

//获取当前的数据的方法
const char*input_buf::data()
{
    return _buf!=NULL?_buf->data+_buf->head:NULL;
}

//重置缓冲区
void input_buf::adjust()
{
    if(_buf!=NULL)
        _buf->adjust();
}

3 网络通信中写输出数据缓冲区 output_buf

        send_data(char *data, int datalen):将data数据写到output_buf中的_buf中

        write2fd(int fd):将output_buf中的_buf数据写到对端fd中

int output_buf::send_data(const char *data, int datalen)
{
    
    if(_buf==NULL)
    {
        //如果outputput_buf里的_buf是空,需要从buf_pool中重新获取
        _buf = buf_pool::instance()->alloc_buf(datalen);
        if(_buf==NULL){
            fprintf(stderr, "no buf for alloc\n");
            return -1;
        }
    }else{
         assert(_buf->head==0);
        if(_buf->capacity-_buf->length < datalen)
        {
            //当前情况不够村,需要重新申请一个buf
            io_buf *new_buf = buf_pool::instance()->alloc_buf(datalen+_buf->length);
            //将之前的_buf数据拷贝到新的buf中
            new_buf->copy(_buf);
            //将之前的_buf放回pool
            buf_pool::instance()->revert(_buf);
            //新申请的buf为当前的io_buf
            _buf = new_buf;
        }
    }

    //将data数据写入io_buf中
    memcpy(_buf->data+_buf->length, data, datalen);
    _buf->length += datalen;
}


//将_buf中的数据写到一个fd中
int output_buf::write2fd(int fd)
{
    assert(_buf!=NULL && _buf->head==0);
    int already_write = 0;
    do{
        already_write = write(fd, _buf->data, _buf->length);
    }while(already_write==-1&&errno==EINTR);

    if(already_write>0)
    {
        //写成功
        _buf->pop(already_write); //把已经处理的数据弹出,后移head
        _buf->adjust();
    }

    //如果fd是非阻塞的,会报already_write == -1 errno==EAGAIN
	if (already_write == -1 && errno == EAGAIN)
	{
		already_write = 0;//表示非阻塞导致的-1不是一个错误,表示是正确的只是写0个字节
	}

	return already_write;
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值