声明在 src\http\ngx_http.h
- ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_listen_opt_t *lsopt);
复制代码 界说在 src\http\ngx_http.c
- ngx_int_t
- ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_listen_opt_t *lsopt)
- {
- in_port_t p;
- ngx_uint_t i;
- struct sockaddr *sa;
- ngx_http_conf_port_t *port;
- ngx_http_core_main_conf_t *cmcf;
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
- if (cmcf->ports == NULL) {
- cmcf->ports = ngx_array_create(cf->temp_pool, 2,
- sizeof(ngx_http_conf_port_t));
- if (cmcf->ports == NULL) {
- return NGX_ERROR;
- }
- }
- sa = lsopt->sockaddr;
- p = ngx_inet_get_port(sa);
- port = cmcf->ports->elts;
- for (i = 0; i < cmcf->ports->nelts; i++) {
- if (p != port[i].port || sa->sa_family != port[i].family) {
- continue;
- }
- /* a port is already in the port list */
- return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
- }
- /* add a port to the port list */
- port = ngx_array_push(cmcf->ports);
- if (port == NULL) {
- return NGX_ERROR;
- }
- port->family = sa->sa_family;
- port->port = p;
- port->addrs.elts = NULL;
- return ngx_http_add_address(cf, cscf, port, lsopt);
- }
复制代码 这个函数是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; 时,参数会被剖析到该结构体中。
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
复制代码 获取 HTTP 核心模块的主设置结构体
界说在
src\http\ngx_http_config.h
- #define ngx_http_conf_get_module_main_conf(cf, module) \
- ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
复制代码
- if (cmcf->ports == NULL) {
- cmcf->ports = ngx_array_create(cf->temp_pool, 2,
- sizeof(ngx_http_conf_port_t));
- if (cmcf->ports == NULL) {
- return NGX_ERROR;
- }
- }
复制代码 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博客
获取监听设置中的套接字地址结构
- p = ngx_inet_get_port(sa);
复制代码 从套接字地址结构中提取端口号 ,并将其转换为主机字节序(Host Byte Order),以便后续逻辑处置惩罚
- port = cmcf->ports->elts;
- for (i = 0; i < cmcf->ports->nelts; i++) {
- if (p != port[i].port || sa->sa_family != port[i].family) {
- continue;
- }
- /* a port is already in the port list */
- return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
- }
复制代码 遍历已存在的端口列表
若端口号或协议族不匹配,跳过当前端口,继续检查下一个
匹配成功
ngx_http_add_addresses :将当前监听地址(lsopt)添加到已存在的端口设置(port)的地址列表中
- 合并同一端口的多个监听设置,避免重复绑定(例如多个 server 块监听 80 端口的不同 IP 地址)。
- 减少 bind() 系统调用次数,提升性能。
此时 ports->nelts=0
- /* add a port to the port list */
- port = ngx_array_push(cmcf->ports);
- if (port == NULL) {
- return NGX_ERROR;
- }
- port->family = sa->sa_family;
- port->port = p;
- port->addrs.elts = NULL;
复制代码 添加一个新元素到数组中
ngx_http_conf_port_t-CSDN博客
- return ngx_http_add_address(cf, cscf, port, lsopt);
复制代码 将新的监听地址(lsopt)添加到指定端口(port)的地址列表中
ngx_http_add_address-CSDN博客
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |