ngx_buf_t使用

本文介绍了如何在Nginx中使用ngx_buf_t发送HTTP响应包体,探讨了ngx_pool_t内存池的用法,强调了全异步服务器下正确分配和使用内存的重要性。
摘要由CSDN通过智能技术生成

3.7.2 将内存中的字符串作为包体发送

调用ngx_http_output_filter方法即可向客户端发送HTTP响应包体,下面查看一下此方法的原型,如下所示。

 
 
  1. ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in); 

ngx_http_output_filter的返回值在mytest例子中不需要处理,通过在ngx_http_mytest_handler方法中返回的方式传递给ngx_http_finalize_request即可。ngx_chain_t结构已经在3.2.6节中介绍过,它仅用于容纳ngx_buf_t缓冲区,所以需要先了解一下如何使用ngx_buf_t分配内存。下面介绍Nginx的内存池是如何分配内存的。

为了减少内存碎片的数量,并通过统一管理来减少代码中出现内存泄漏的可能性,Nginx设计了ngx_pool_t内存池数据结构。本章我们不会深入分析内存池的实现,只关注内存池的用法。在ngx_http_mytest_handler处理方法传来的ngx_http_request_t对象中就有这个请求的内存池管理对象,我们对内存池的操作都可以基于它来进行,这样,在这个请求结束的时候,内存池分配的内存也都会被释放。

 
 
  1. struct ngx_http_request_s {  
  2.     …  
  3.     ngx_pool_t *pool;  
  4.     …  
  5. }; 

实际上,在r中可以获得许多内存池对象,这些内存池的大小、意义及生存期各不相同。第3部分会涉及许多内存池,本章使用r->pool内存池即可。有了ngx_pool_t对象后,可以从内存池中分配内存。例如,下面这个基本的申请分配内存的方法:

 
 
  1. void *ngx_palloc(ngx_pool_t *pool, size_t size); 

其中,ngx_palloc函数将会从pool内存池中分配到size字节的内存,并返回这段内存的起始地址。如果返回NULL空指针,则表示分配失败。还有一个封装了ngx_palloc的函数ngx_pcalloc,它多做了一件事,就是把ngx_palloc申请到的内存块全部置为0,虽然,多数情况下更适合用ngx_pcalloc来分配内存。

假如要分配一个ngx_buf_t结构,可以这样做:

 
 
  1. ngx_buf_t* b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); 

这样,ngx_buf_t中的成员指向的内存仍然可以继续分配,例如:

 
 
  1. b->start = (u_char*)ngx_pcalloc(r->pool, 128);  
  2. b->pos = b->start;  
  3. b->last = b->start;  
  4. b->end = b->last + 128;  
  5. b->temporary = 1

实际上,Nginx还封装了一个生成ngx_buf_t的简便方法,它完全等价于上面的6行语句,如下所示。
 

 
 
  1. ngx_buf_t *b = ngx_create_temp_buf(r->pool, 128); 

分配完内存后,可以向这段内存写入数据。当写完数据后,要让b->last指针指向数据的末尾,如果b->last与b->pos相等,那么HTTP框架是不会发送一个字节的包体的。

最后,把上面的ngx_buf_t *b用ngx_chain_t传给ngx_http_output_filter方法就可以发送HTTP响应的包体内容了。例如:

 
 
  1. ngx_chain_t out;  
  2. out.buf = b;  
  3. out.next = NULL;  
  4.  
  5. return ngx_http_output_filter(r, &out); 

注意 在向用户发送响应包体时,必须牢记Nginx是全异步的服务器,也就是说,不可以在进程的栈里分配内存并将其作为包体发送。当ngx_http_output_filter方法返回时,可能由于TCP连接上的缓冲区还不可写,所以导致ngx_buf_t缓冲区指向的内存还没有发送,可这时方法返回已把控制权交给Nginx了,又会导致栈里的内存被释放,最后就会造成内存越界错误。因此,在发送响应包体时,尽量将ngx_buf_t中的pos指针指向从内存池里分配的内存。

参考:http://book.51cto.com/art/201303/386675.htm

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值