ngx_http_add_listen

诗林  金牌会员 | 2025-3-25 02:26:10 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 674|帖子 674|积分 2022

声明在 src\http\ngx_http.h 
  1. ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
  2.     ngx_http_listen_opt_t *lsopt);
复制代码
界说在 src\http\ngx_http.c
  1. ngx_int_t
  2. ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
  3.     ngx_http_listen_opt_t *lsopt)
  4. {
  5.     in_port_t                   p;
  6.     ngx_uint_t                  i;
  7.     struct sockaddr            *sa;
  8.     ngx_http_conf_port_t       *port;
  9.     ngx_http_core_main_conf_t  *cmcf;
  10.     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
  11.     if (cmcf->ports == NULL) {
  12.         cmcf->ports = ngx_array_create(cf->temp_pool, 2,
  13.                                        sizeof(ngx_http_conf_port_t));
  14.         if (cmcf->ports == NULL) {
  15.             return NGX_ERROR;
  16.         }
  17.     }
  18.     sa = lsopt->sockaddr;
  19.     p = ngx_inet_get_port(sa);
  20.     port = cmcf->ports->elts;
  21.     for (i = 0; i < cmcf->ports->nelts; i++) {
  22.         if (p != port[i].port || sa->sa_family != port[i].family) {
  23.             continue;
  24.         }
  25.         /* a port is already in the port list */
  26.         return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
  27.     }
  28.     /* add a port to the port list */
  29.     port = ngx_array_push(cmcf->ports);
  30.     if (port == NULL) {
  31.         return NGX_ERROR;
  32.     }
  33.     port->family = sa->sa_family;
  34.     port->port = p;
  35.     port->addrs.elts = NULL;
  36.     return ngx_http_add_address(cf, cscf, port, lsopt);
  37. }
复制代码
这个函数是Nginx在剖析设置时用于添加监听端口的核心逻辑

函数署名

   返回值:ngx_int_t

  
  

  • NGX_OK(0):成功添加监听设置。
  • NGX_ERROR(-1):内存分配失败或地址冲突等错误
  
  参数

  ngx_conf_t *cf

  

  • 范例 :指向 ngx_conf_t 结构体的指针。
  • 作用
    表现 Nginx 设置剖析的上下文(Context),包含当前剖析的设置文件路径、内存池(temp_pool)、日志对象等关键信息
  
  ngx_http_core_srv_conf_t *cscf

  

  • 范例 :指向 ngx_http_core_srv_conf_t 结构体的指针。
  • 作用
    表现当前正在设置的 HTTP server 块的核心设置。每个 server 块在 Nginx 中对应一个假造主机,该结构体存储了与该假造主机相干的设置信息。
  
  ngx_http_listen_opt_t *lsopt

  

  • 范例 :指向 ngx_http_listen_opt_t 结构体的指针。
  • 作用
    封装了从设置文件中剖析出的 listen 指令参数。例如,用户设置 listen 80; 或 listen 443 ssl; 时,参数会被剖析到该结构体中。
  
  1. cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
复制代码
   获取 HTTP 核心模块的主设置结构体

  界说在

  src\http\ngx_http_config.h

  1. #define ngx_http_conf_get_module_main_conf(cf, module)                        \
  2.     ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
复制代码

  1.     if (cmcf->ports == NULL) {
  2.         cmcf->ports = ngx_array_create(cf->temp_pool, 2,
  3.                                        sizeof(ngx_http_conf_port_t));
  4.         if (cmcf->ports == NULL) {
  5.             return NGX_ERROR;
  6.         }
  7.     }
复制代码
   cmcf->ports 是 ngx_http_core_main_conf_t 结构体中的一个动态数组(ngx_array_t),用于存储所有监听端口的设置 

  如果 ports 为 NULL,表现这是初次添加监听端口,需要初始化数组

  

  • cf->temp_pool :内存池(ngx_pool_t),用于分配数组内存。设置阶段的临时内存池(temp_pool)会在设置剖析完成后被释放或重置。
  • 2 :数组的初始容量(预分配 2 个元素的空间),减少后续扩容的次数。
  • sizeof(ngx_http_conf_port_t) :数组元素的巨细,每个元素对应一个监听端口的设置。
  

  ngx_http_core_main_conf_t-CSDN博客

  1.     sa = lsopt->sockaddr;
复制代码
   获取监听设置中的套接字地址结构
  1.     p = ngx_inet_get_port(sa);
复制代码
  从套接字地址结构中提取端口号 ,并将其转换为主机字节序(Host Byte Order),以便后续逻辑处置惩罚
   
  1.     port = cmcf->ports->elts;
  2.     for (i = 0; i < cmcf->ports->nelts; i++) {
  3.         if (p != port[i].port || sa->sa_family != port[i].family) {
  4.             continue;
  5.         }
  6.         /* a port is already in the port list */
  7.         return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
  8.     }
复制代码
   遍历已存在的端口列表
  若端口号或协议族不匹配,跳过当前端口,继续检查下一个
  匹配成功 

  ngx_http_add_addresses :将当前监听地址(lsopt)添加到已存在的端口设置(port)的地址列表中
  

  • 合并同一端口的多个监听设置,避免重复绑定(例如多个 server 块监听 80 端口的不同 IP 地址)。
  • 减少 bind() 系统调用次数,提升性能。
  此时 ports->nelts=0

  1.     /* add a port to the port list */
  2.     port = ngx_array_push(cmcf->ports);
  3.     if (port == NULL) {
  4.         return NGX_ERROR;
  5.     }
  6.     port->family = sa->sa_family;
  7.     port->port = p;
  8.     port->addrs.elts = NULL;
复制代码
  添加一个新元素到数组中 
   ngx_http_conf_port_t-CSDN博客
  1. return ngx_http_add_address(cf, cscf, port, lsopt);
复制代码
   将新的监听地址(lsopt)添加到指定端口(port)的地址列表中
  

  ngx_http_add_address-CSDN博客


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

诗林

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表