从这一篇文章开始,我们分析listen指令的解析过程,listen指令的配置如下:从nginx.org的手册中我们可以获取listen的使用方法:
listenaddress[:port][default_server][setfib=number][backlog=number][rcvbuf=size][sndbuf=size][accept_filter=filter][deferred][bind][ipv6only=on|off][ssl][so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
一个listen指令携带的参数是很复杂的。我们一般很少关注那些不太常用的参数,以下是一些常用的配置方式:
listen127.0.0.1不加端口,默认监听80端口;
listenlocalhost:8000
解析listen指令中的uri和端口
从上面的内容知道,listen有多种用法,我们在解析的时候需要获取到listen指令的端口号和uri部分,nginx提供了ngx_parse_url()方法来解析uri和port,该函数在解析listen指令的时候会被调用。
ngx_parse_url(ngx_pool_t*pool,ngx_url_t*u)
//这里是解析unixdomain的协议
if(len>=5&&ngx_strncasecmp(p,(u_char*)"unix:",5)==0){
returnngx_parse_unix_domain_url(pool,u);
returnngx_parse_inet6_url(pool,u);
returnngx_parse_inet_url(pool,u);
}
我们使用的是ipv4协议,这里分析ngx_parse_inet_url()函数
ngx_parse_inet_url(ngx_pool_t*pool,ngx_url_t*u)
u_char*p,*host,*port,*last,*uri,*args;
u->socklen=sizeof(structsockaddr_in);
sin=(structsockaddr_in*)&u->sockaddr;
sin->sin_family=af_inet;//ipv4类型
host=u->url.data;//"80"
last=host+u->url.len;//host的最后字符的位置
port=ngx_strlchr(host,last,':');//找到port,这里为null
uri=ngx_strlchr(host,last,'/');//找到uri,这里为null
args=ngx_strlchr(host,last,'?');//找到参数args,这里为null
if(uri==null||args<uri){
if(u->listen||!u->uri_part){
sin->sin_port=htons((in_port_t)n);
u->port_text.data=port;
n=ngx_atoi(host,last-host);
sin->sin_port=htons((in_port_t)n);
u->port_text.len=last-host;
u->port_text.data=host;
u->port=u->default_port;
sin->sin_port=htons(u->default_port);
if(u->listen&&len==1&&*host=='*'){
sin->sin_addr.s_addr=inaddr_any;
sin->sin_addr.s_addr=ngx_inet_addr(host,len);
if(sin->sin_addr.s_addr!=inaddr_none){
if(sin->sin_addr.s_addr==inaddr_any){
u->addrs=ngx_pcalloc(pool,sizeof(ngx_addr_t));
sin=ngx_pcalloc(pool,sizeof(structsockaddr_in));
ngx_memcpy(sin,&u->sockaddr,sizeof(structsockaddr_in));
u->addrs[0].sockaddr=(structsockaddr*)sin;
u->addrs[0].socklen=sizeof(structsockaddr_in);
p=ngx_pnalloc(pool,u->host.len+sizeof(":65535")-1);
u->addrs[0].name.len=ngx_sprintf(p,"%v:%d",
&u->host,u->port)-p;
u->addrs[0].name.data=p;
if(ngx_inet_resolve_host(pool,u)!=ngx_ok){

u->socklen=u->addrs[0].socklen;
ngx_memcpy(&u->sockaddr,u->addrs[0].sockaddr,u->addrs[0].socklen);
sin6=(structsockaddr_in6*)&u->sockaddr;
if(in6_is_addr_unspecified(&sin6->sin6_addr)){
sin=(structsockaddr_in*)&u->sockaddr;
if(sin->sin_addr.s_addr==inaddr_any){
}
这个函数就是解析了我们listen的地址和端口号,我们的配置文件中,端口号为80,并没有配置监听地址,所以u->wildcard=1,表示这是一个通配符,要监听该服务器所有ip地址的这个端口号。
下面从源码中看一下listen的配置:
ngx_http_srv_conf|ngx_conf_1more,
ngx_http_srv_conf_offset,
ngx_http_core_listen(ngx_conf_t*cf,ngx_command_t*cmd,void*conf)
ngx_http_core_srv_conf_t*cscf=conf;
ngx_http_listen_opt_tlsopt;
value=cf->args->elts;
ngx_memzero(&u,sizeof(ngx_url_t));
if(ngx_parse_url(cf->pool,&u)!=ngx_ok){
ngx_memzero(&lsopt,sizeof(ngx_http_listen_opt_t));
ngx_memcpy(&lsopt.sockaddr.sockaddr,&u.sockaddr,u.socklen);
lsopt.backlog=ngx_listen_backlog;
#if(ngx_have_tcp_fastopen)
lsopt.wildcard=u.wildcard;
(void)ngx_sock_ntop(&lsopt.sockaddr.sockaddr,lsopt.socklen,lsopt.addr,
for(n=2;n<cf->args->nelts;n++){
if(ngx_strcmp(value[n].data,"default_server")==0
||ngx_strcmp(value[n].data,"default")==0)
//这里面的其他代码都是处理listen的各种参数,对我们这里的分析没有用处
if(ngx_http_add_listen(cf,cscf,&lsopt)==ngx_ok){
}
//cf:配置结构体
//cscf:listen指令所在的server的配置结构体
//lsopt:ngx_http_core_listen()生成的listenoption
ngx_http_add_listen(ngx_conf_t*cf,ngx_http_core_srv_conf_t*cscf,
ngx_http_listen_opt_t*lsopt)
ngx_http_conf_port_t*port;
ngx_http_core_main_conf_t*cmcf;
//获取ngx_http_core_module模块的main_conf结构体ngx_http_core_main_conf_t
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){
sa=&lsopt->sockaddr.sockaddr;
port=cmcf->ports->elts;
for(i=0;i<cmcf->ports->nelts;i++){
if(p!=port[i].port||sa->sa_family!=port[i].family){
returnngx_http_add_addresses(cf,cscf,&port[i],lsopt);
port=ngx_array_push(cmcf->ports);
port->family=sa->sa_family;
port->addrs.elts=null;
returnngx_http_add_address(cf,cscf,port,lsopt);
}
以上就是nginx中的listen指令怎么用的详细内容,更多请关注主机测评网其它相关文章!
本文来源:国外服务器--nginx中的listen指令怎么用(nginxindex指令)
本文地址:https://www.idcbaba.com/guowai/4121.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 1919100645@qq.com 举报,一经查实,本站将立刻删除。



