博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nginx对端口的处理 -- 第三篇
阅读量:7081 次
发布时间:2019-06-28

本文共 9565 字,大约阅读时间需要 31 分钟。

微信公众号:

关注可了解更多的Nginx知识。任何问题或建议,请公众号留言;
关注公众号,有趣有内涵的文章第一时间送达!

ngx_open_listening_sockets

1ngx_int_t   2ngx_open_listening_sockets(ngx_cycle_t *cycle)   3{
4    int               reuseaddr; 5    ngx_uint_t        i, tries, failed; 6    ngx_err_t         err; 7    ngx_log_t        *log; 8    ngx_socket_t      s; 9    ngx_listening_t  *ls; 10 11    reuseaddr = 1; 12#if (NGX_SUPPRESS_WARN) 13    failed = 0; 14#endif 15 16    log = cycle->log; 17 18    /* TODO: configurable try number */ 19 20    for (tries = 5; tries; tries--) {
21        failed = 0; 22 23        /* for each listening socket */ 24 25        ls = cycle->listening.elts; 26        for (i = 0; i < cycle->listening.nelts; i++) {
27 28            if (ls[i].ignore) {
29                continue; 30            } 31 32#if (NGX_HAVE_REUSEPORT) 33 34            if (ls[i].add_reuseport) {
35 36                /* 37                 * to allow transition from a socket without SO_REUSEPORT 38                 * to multiple sockets with SO_REUSEPORT, we have to set 39                 * SO_REUSEPORT on the old socket before opening new ones 40                 */ 41 42                int  reuseport = 1; 43 44                if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT, 45                               (const void *) &reuseport, sizeof(int)) 46                    == -1) 47                {
48                    ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, 49                                  "setsockopt(SO_REUSEPORT) %V failed, ignored", 50                                  &ls[i].addr_text); 51                } 52 53                ls[i].add_reuseport = 0; 54            } 55#endif 56 57            if (ls[i].fd != (ngx_socket_t) -1) {
58                continue; 59            } 60 61            if (ls[i].inherited) {
62 63                /* TODO: close on exit */ 64                /* TODO: nonblocking */ 65                /* TODO: deferred accept */ 66 67                continue; 68            } 69 70            s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0); 71 72            if (s == (ngx_socket_t) -1) {
73                ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 74                              ngx_socket_n " %V failed", &ls[i].addr_text); 75                return NGX_ERROR; 76            } 77 78            if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 79                           (const void *) &reuseaddr, sizeof(int)) 80                == -1) 81            {
82                ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 83                              "setsockopt(SO_REUSEADDR) %V failed", 84                              &ls[i].addr_text); 85 86                if (ngx_close_socket(s) == -1) {
87                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 88                                  ngx_close_socket_n " %V failed", 89                                  &ls[i].addr_text); 90                } 91 92                return NGX_ERROR; 93            } 94 95#if (NGX_HAVE_REUSEPORT) 96 97            if (ls[i].reuseport && !ngx_test_config) {
98                int  reuseport; 99 100                reuseport = 1; 101 102                if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, 103                               (const void *) &reuseport, sizeof(int)) 104                    == -1) 105                {
106                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 107                                  "setsockopt(SO_REUSEPORT) %V failed", 108                                  &ls[i].addr_text); 109 110                    if (ngx_close_socket(s) == -1) {
111                        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 112                                      ngx_close_socket_n " %V failed", 113                                      &ls[i].addr_text); 114                    } 115 116                    return NGX_ERROR; 117                } 118            } 119#endif 120 121#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) 122 123            if (ls[i].sockaddr->sa_family == AF_INET6) {
124                int  ipv6only; 125 126                ipv6only = ls[i].ipv6only; 127 128                if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 129                               (const void *) &ipv6only, sizeof(int)) 130                    == -1) 131                {
132                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 133                                  "setsockopt(IPV6_V6ONLY) %V failed, ignored", 134                                  &ls[i].addr_text); 135                } 136            } 137#endif 138            /* TODO: close on exit */ 139 140            if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
141                if (ngx_nonblocking(s) == -1) {
142                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 143                                  ngx_nonblocking_n " %V failed", 144                                  &ls[i].addr_text); 145 146                    if (ngx_close_socket(s) == -1) {
147                        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 148                                      ngx_close_socket_n " %V failed", 149                                      &ls[i].addr_text); 150                    } 151 152                    return NGX_ERROR; 153                } 154            } 155 156            ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0, 157                           "bind() %V #%d ", &ls[i].addr_text, s); 158 159            if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
160                err = ngx_socket_errno; 161 162                if (err != NGX_EADDRINUSE || !ngx_test_config) {
163                    ngx_log_error(NGX_LOG_EMERG, log, err, 164                                  "bind() to %V failed", &ls[i].addr_text); 165                } 166 167                if (ngx_close_socket(s) == -1) {
168                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 169                                  ngx_close_socket_n " %V failed", 170                                  &ls[i].addr_text); 171                } 172 173                if (err != NGX_EADDRINUSE) {
174                    return NGX_ERROR; 175                } 176 177                if (!ngx_test_config) {
178                    failed = 1; 179                } 180 181                continue; 182            } 183 184#if (NGX_HAVE_UNIX_DOMAIN) 185 186            if (ls[i].sockaddr->sa_family == AF_UNIX) {
187                mode_t   mode; 188                u_char  *name; 189 190                name = ls[i].addr_text.data + sizeof("unix:") - 1; 191                mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); 192 193                if (chmod((char *) name, mode) == -1) {
194                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 195                                  "chmod() \"%s\" failed", name); 196                } 197 198                if (ngx_test_config) {
199                    if (ngx_delete_file(name) == NGX_FILE_ERROR) {
200                        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 201                                      ngx_delete_file_n " %s failed", name); 202                    } 203                } 204            } 205#endif 206 207            if (ls[i].type != SOCK_STREAM) {
208                ls[i].fd = s; 209                continue; 210            } 211 212            if (listen(s, ls[i].backlog) == -1) {
213                err = ngx_socket_errno; 214 215                /* 216                 * on OpenVZ after suspend/resume EADDRINUSE 217                 * may be returned by listen() instead of bind(), see 218                 * https://bugzilla.openvz.org/show_bug.cgi?id=2470 219                 */ 220 221                if (err != NGX_EADDRINUSE || !ngx_test_config) {
222                    ngx_log_error(NGX_LOG_EMERG, log, err, 223                                  "listen() to %V, backlog %d failed", 224                                  &ls[i].addr_text, ls[i].backlog); 225                } 226 227                if (ngx_close_socket(s) == -1) {
228                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 229                                  ngx_close_socket_n " %V failed", 230                                  &ls[i].addr_text); 231                } 232 233                if (err != NGX_EADDRINUSE) {
234                    return NGX_ERROR; 235                } 236 237                if (!ngx_test_config) {
238                    failed = 1; 239                } 240 241                continue; 242            } 243 244            ls[i].listen = 1; 245 246            ls[i].fd = s; 247        } 248 249        if (!failed) {
250            break; 251        } 252 253        /* TODO: delay configurable */ 254 255        ngx_log_error(NGX_LOG_NOTICE, log, 0, 256                      "try again to bind() after 500ms"); 257 258        ngx_msleep(500); 259    } 260 261    if (failed) {
262        ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()"); 263        return NGX_ERROR; 264    } 265 266    return NGX_OK; 267}

这个函数的功能很简单,就是打开socket,然后bind,然后listen,仅此而已,通过这个函数,我么已经对这个端口和IP地址进行了listen,当有新的连接的时候,就会accept新的连接。

内存布局如下:

内存布局内存布局

喜欢本文的朋友们,欢迎长按下图关注订阅号郑尔多斯,更多精彩内容第一时间送达

郑尔多斯郑尔多斯

转载于:https://www.cnblogs.com/zhengerduosi/p/10087975.html

你可能感兴趣的文章
QTreeWidget 获取被双击的子项的层次路径
查看>>
如何调整工作激情
查看>>
数据仓库专题(10)-文本事实和杂项维度
查看>>
VC6下实现remove_reference的方法。
查看>>
数据备份和还原
查看>>
Angular企业级开发(3)-Angular MVC实现
查看>>
SMS系列之一:部署SMS2003 + SP3
查看>>
查看mysql进程--show processlist
查看>>
ProtecTIER网关演绎重复数据删除的硬道理
查看>>
Android 播放Gif 动画
查看>>
(原创)创建windows域---深入理解域概念
查看>>
虚幻4,BP写了一个简单的三线跑酷工程
查看>>
“10亿元身价”CEO的6个密码
查看>>
C++/CLI思辨录之内部指针的两面性
查看>>
【英语天天读】I want I do I get
查看>>
DIV层+CSS实现锁屏
查看>>
浅谈C/C++中的顺序点和副作用
查看>>
每周一书-《做自己-鬼脚七自媒体第一季》
查看>>
如何删除JAVA集合中的元素
查看>>
jQuery 事件 - trigger() 方法
查看>>