关闭

nginx----ngx_buf

348人阅读 评论(0) 收藏 举报
分类:

在ngx_buf.h文件中,定义了ngx_chain_t和ngx_buf_t两个结构体。其中chain起到一个链的作用,将待发送的数据包串联起来,而buf则是chain中的每一个节点。

ngx_buf_t的数据结构如下:

struct ngx_buf_s {
    u_char          *pos;
    u_char          *last;
    off_t            file_pos;
    off_t            file_last;

    u_char          *start;         /* start of buffer */
    u_char          *end;           /* end of buffer */
    ngx_buf_tag_t    tag;
    ngx_file_t      *file;
    ngx_buf_t       *shadow;


    /* the buf's content could be changed */
    unsigned         temporary:1;

    /*
     * the buf's content is in a memory cache or in a read only memory
     * and must not be changed
     */
    unsigned         memory:1;

    /* the buf's content is mmap()ed and must not be changed */
    unsigned         mmap:1;

    unsigned         recycled:1;
    unsigned         in_file:1;
    unsigned         flush:1;
    unsigned         sync:1;
    unsigned         last_buf:1;
    unsigned         last_in_chain:1;

    unsigned         last_shadow:1;
    unsigned         temp_file:1;

    /* STUB */ int   num;
};

buf结构体中的成员变量主要是用于指示数据存在的位置以及一些相关的标志位。

由上可知,buf用来指示chain中每个节点的实际数据的位置,实际数据可以存放在内存中,也可以存放在文件中。当在内存中时,用pos和last两个变量来指示数据存在的地址区间,当存在于文件中时,用file_pos和file_last来指示数据在文件中起始位置的偏移量。

ngx_chain_t的数据结构如下:

struct ngx_chain_s {
    ngx_buf_t    *buf;
    ngx_chain_t  *next;
};
chain通过next指针将多个buf 节点串联成链,然后等待一起发送。

一条ngx_chain的简单示意图如下,以数据存放在内存中为例:


由上图可知,一个数据包链是由多个ngx_chain通过next指针链接形成的,其中每一个chain节点都携带一个buf结构体,用于指示实际数据的位置。实际数据存放在内存块或文件中,最终形成的数据包链为上面的这种三级结构。

buf 一般都是从内存池中申请内存的,因此不同的buf中的数据可能存在于同一块内存块中,此时buf结构体中的start和end相同,但是通过pos和last变量来区分不同数据的起始位置。

当最后一个chain的next变量指向NULL时,数据包才会发送出去,否则将会一直遍历下去。

创建一条buf链

ngx_chain_t *
ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
{
    u_char       *p;
    ngx_int_t     i;
    ngx_buf_t    *b;
    ngx_chain_t  *chain, *cl, **ll;

    p = ngx_palloc(pool, bufs->num * bufs->size);   //从内存池中为分配buf指向的实际存储空间
    if (p == NULL) {
        return NULL;
    }

    ll = &chain;

    for (i = 0; i < bufs->num; i++) {

        b = ngx_calloc_buf(pool);  //为每一个buf 结构分配内存
        if (b == NULL) {
            return NULL;
        }

        b->pos = p;   //设置每一个buf 的每一个字段的值
        b->last = p;
        b->temporary = 1;

        b->start = p;
        p += bufs->size;
        b->end = p;

        cl = ngx_alloc_chain_link(pool);   //为chain中的每一个节点分配内存
        if (cl == NULL) {
            return NULL;
        }

        cl->buf = b;    //将chain节点和buf结构绑定到一起
        *ll = cl;       //将每一个chain节点通过next指针串联成一条链
        ll = &cl->next;
    }

    *ll = NULL;   //chain中最后一个节点的next指针指向NULL,表示一条链的结束

    return chain;
}
最终生成的结构示意图如下:



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:85577次
    • 积分:2115
    • 等级:
    • 排名:第18058名
    • 原创:121篇
    • 转载:24篇
    • 译文:0篇
    • 评论:10条
    最新评论