简体   繁体   中英

Can backlog value that is passed to listen() call be modified later on without clossing the listening socket in Winsock2 C++ on Windows?

First of, I have seen many questions related to backlog but known addresses the mystery whether a backlog value that has been initially set in a listen() call can be changed later on without closing the socket (and re-calling the bind() & listen())?

What I want to do is to dynamically change the backlog at runtime for my server application. At present, the server had issues with startup due to thundering herd problem (all clients attempt to connect at startup). There are 500 clients. To address this issue I reduced the backlog to 10. This has greatly helped the server to recover from the startup load. However, once the server has recovered I would like to enlarge the underlying queue by modifying the backlog value.

So, is there a way to change the backlog without closing the socket.

Thing that I saw over the internet which won't work is to make a second listen() call over the same listening socket by passing a different backlog value. This is clever thinking however the MSDN clearly states that it will have no effect on the backlog parameter.

On Linux, you can call listen() again to change the backlog. Nginx has the following code:

ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
    if (ngx_open_listening_sockets(cycle) != NGX_OK) {
        goto failed;
    }

    if (!ngx_test_config) {
        ngx_configure_listening_sockets(cycle);
    }
}

ngx_int_t
ngx_open_listening_sockets(ngx_cycle_t *cycle)
{
            if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
                // ...
            }

            if (listen(s, ls[i].backlog) == -1) {
                // ...
            }
}

void
ngx_configure_listening_sockets(ngx_cycle_t *cycle)
{
    // set socket options
    // ...
    
        if (ls[i].listen) {
            /* change backlog via listen() */
            if (listen(ls[i].fd, ls[i].backlog) == -1) {
                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                              "listen() to %V, backlog %d failed, ignored",
                              &ls[i].addr_text, ls[i].backlog);
            }
        }
}

Nginx calls listen() again to change the backlog after set some socket options on the listening socket.

I wrote a test program to call listen() twice, which succeeded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM