session中的buffer巧用

一般可以把session和read_buffer和write_buffer封装成结构体。 session可以是单一的fd,也可以是fd和其相关信息的再封装。

形如:

typedef struct sStream {

 int fd;    /*session*/

 

unsigned int max_buffer_size;   /*读写buffer最大值*/

 

void* read_buffer;

unsigned int  read_buffer_len;   /*已有数据长度*/

 

void* write_buffer;

unsigned int write_buffer_len;  /*已有数据长度*/

}Stream;

 

这样封装起来实质上就是在内核fd的缓冲区机制上又在应用层加了一个缓冲机制。 这样就可以把内核层的read和write封装成我们自己的read API和write API。应用方法大略如下:

write:

比如自己封装的write API为: int self_write(Stream* st,  void* buf,   unsigned int   len);

/*输入参数正确的前提下*/

 

int write_direct(Stream* st, void* buf,  unsigned int len)

{

     int count = 0;

    int left = len;

    const char* cur_buf = buf;

     while(left  > 0)

    {

        count = write(st->fd, cur_buf,  left);

 

       if (count < 0)

       {

               if (left == len)

                  return -1;

              else

                return len - left;

       }

        left  -= count;

       cur_buf  +=  count;

    }  

   return len;

}

 

int write_fresh(Stream* st)

{

    char* buf = st->write_buffer;

    int len = st->write_buffer_len;

    int count = 0;

   while (len > 0)

  {

       count = write(st->fd, buf, len);

      if (count < 0)

      {

            memmove(st->write_buffer,  buf,  left);

            st->write_buffer = left;

             return -1;

      }

       len -= count;

      buf  += count;

  }

 st->write_buffer_len = 0;

 return 0;

}

int write_internal_buffer(Stream* st, void* buf,  unsigned int  len)

{

     memcpy(st->write_buffer + st->write_buffer_len,  buf,    len);

     st->write_buffer_len += len;

     return len;

}

int self_write(Stream* st,  void* buf,   unsigned int   len )

{

   unsigned int count = len;

   unsigned int buf_len = st->write_buffer_len;

   int iRet = -1;

   if ( count + len > st->max_buffer_size)

  {

        iRet =  write_fresh(st);

        if (iRet == -1)

            return -1;

         if (count > max_buffer_size)

        {

               iRet = write_direct(st, buf, len);

               return iRet;                        

        }

  }

  iRet = write_internal_buffer(st, buf, len);

   return iRet;

}

 

read:

比如自己封装的read API为: int self_read(Stream* st,  void* buf,   unsigned int   len);

/*输入参数正确的前提下*/

int  read_from_internal_buffer(Stream* st, void* buf ,   unsigned int len)   /*从内部buffer中读, 有指针移动*/

{

        memcpy(buf, st->read_buffer,  len);

       memmove(st->read_buffer,  st->read_buffer + len;  st->read_buffer_len - len);

        st->read_buffer_len -= len;

        return len;

}

 

int read_flush(Stream*st, void* buf)   /*把buffer中的所有都读出来*/

{

    int len = st->read_buffer_len;

    memcpy(buf, st->read_buffer, len);

    st->read_buffer_len = 0;

    return  len;

 

int read_direct(Stream* st,  void* buf, unsigned int len)   /*直接从网络读取*/

{

      int readen = 0;

      int left = len;

      char* cur_buf = buf;

      while(left   > 0)

      {

           readen = read(st->fd, cur_buf,  left);

          if (readen == -1)

          {

                if (left == len)

                  return -1;

               else

                  return len - left;

          }

            left -= readen;

            cur_buf += readen;

      }

     return len;

}

int read_to_buffer(Stream* st)   /*填满内部buffer,起初是空的*/

{

      int count = 0;

      int len = st->max_buffer_size ;

      char* buf = st->read_buffer ;

      while(len > 0)

      {

            count = read(st->fd, buf, len);

            if (count == -1)

            {

                if (len == st->max_buffer_size )

                     return -1;

                else

                    return st->max_buffer_size - len;

            }

            len -= count;

           buf += count;

      }

     st->read_buffer_len = st->max_buffer_size;

      return st->max_buffer_len;

}

int self_read(Stream* st, char* buf, unsigned int len)

{

    int iRet = -1;

    int writen = 0;

    if (len <=  st->read_buffer_len)           /*如果内部buffer数据够用*/

   {

       iRet = read_from_internal_buffer(st,  buf, len);    /*直接读fd的内部buffer*/

       return iRet;

  }

  else     /*内部buffer数据不够用*/

 {

       writen = read_flush(st, buf);    /*先把内部buffer数据全读出来*/

        len -= writen;

        buf += writen;

        if (len > st->max_buffer_size)    /*上面读完之后还需要的数据大于buffer容量*/

       {

             iRet = read_direct(st, buf, len);   /*直接从fd读*/

             if (iRet == -1)

                  return writen;

            else

                return writen + iRet;

       }

      /*上面读完之后还需要的数据量小于buffer的容量*/

      iRet = read_to_buffer(st);    /*先从fd把内部buffer读满*/

     if (iRet == -1)

         return writen;

      iRet = read_from_internal_buffer(st, buf, len);  /*再从内部buffer读余下的数据*/

     return writen + iRet;

 }

 

}

 

以上代码只是简单地把buffer运用思想体现出来了,真正用的时候还需要判断各种临界条件,参数合法性等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值