开发者

Where does the mysterious 200 connection come from?

开发者 https://www.devze.com 2023-02-16 11:15 出处:网络
Hey guys, i\'m a newbie to async-programming, this is probably a stupid question, but it indeed drove me crazy!!

Hey guys, i'm a newbie to async-programming, this is probably a stupid question, but it indeed drove me crazy!!

Here's the code (it just modified a bit from boost.asio's sample):

server.cpp:

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service)
        : acceptor_(io_service, tcp::endpoint(tcp::v4(), 10000)),limit(0)
    {
        start_accept();
    }

private:
    void start_accept()
    {
        while(1)
        {
            if(limit <= 10)
            {
                std::cout << limit << std::endl;
                break;
            }
        }

        tcp::socket* socket = new tcp::socket(acceptor_.i开发者_如何学Co_service());

        acceptor_.async_accept(*socket,
            boost::bind(&tcp_server::handle_accept, this, boost::asio::placeholders::error));
    }

    void handle_accept(const boost::system::error_code& error)
    {
        if (!error)
        {
            ++limit ;
            start_accept();
        }
    }

    tcp::acceptor acceptor_;

    int limit;
};

int main()
{
    try
    {
        boost::asio::io_service io_service;
        tcp_server server(io_service);
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

client.cpp:

int main(int argc, char* argv[])
{
    int i = 0;

    while(1)
    {
        try
        {
            boost::asio::io_service io_service;

            tcp::resolver resolver(io_service);
            tcp::resolver::query query("127.0.0.1", "10000");
            tcp::resolver::iterator endpoint_iterator =resolver.resolve(query);
            tcp::endpoint endpoint = *endpoint_iterator;

            tcp::socket socket(io_service);
            socket.close();
            socket.connect(endpoint);

            std::cout << i++ << std::endl;
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }

    return 0;
}

I just wanna limit server to accept 10 client. However, client cout the error information after it cout "amazing" 210 (never more or less) continuous numbers. What happend??


I've changed server.cpp a bit. First reconfigured acceptor_ on constructor. Removed while loop, added acceptor_.close();

#include <boost/asio/io_service.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using namespace boost::asio;
using namespace boost::asio::ip;

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service)
        : acceptor_(io_service),limit(0)
    {
        tcp::endpoint endpoint(tcp::v4(), 10000);
        acceptor_.open(endpoint.protocol());
        acceptor_.bind(endpoint);
        acceptor_.listen(1); //accept 1 connection at a time
        start_accept();
    }

private:
    void start_accept()
    {
        tcp::socket* socket = new tcp::socket(acceptor_.io_service());
        acceptor_.async_accept(*socket,
            boost::bind(
                &tcp_server::handle_accept,
                this,
                socket,
                boost::asio::placeholders::error));
    }

    void handle_accept(tcp::socket* s, const boost::system::error_code& error)
    {
        if (!error)
        {
            ++limit;
            if (limit < 9)
            {
                start_accept();
            }
            else
            {
                acceptor_.close();
            }           

        }
    }

    tcp::acceptor acceptor_;

    int limit;
};

int main()
{
    try
    {
        boost::asio::io_service io_service;
        tcp_server server(io_service);
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

I suppose, default acceptor can async_accept 200 connection events at a time. You open a socket and close it from the client side in an infinite loop. As a result you open and close a connection 200 times, but it is still 1 connection, 1 socket.

Capping it to 1 by calling listen(1), would force the acceptor to fire an event. You increase the count, then client closes the connection. This way you correctly count each connection event.

Last note: async io uses 1 thread to process connection events, retrieved data etc... Thus, use of mutexes are not necessary.

0

精彩评论

暂无评论...
验证码 换一张
取 消