c++ - 神秘的200连接从何而来?

标签 c++ boost-asio

大家好,我是异步编程的新手,这可能是个愚蠢的问题,但它确实让我抓狂!!

这是代码(它只是从 boost.asio 的示例中修改了一点):

服务器.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_.io_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;
}

客户端.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;
}

我只想限制服务器接受 10 个客户端。 然而,客户端在计算出“惊人的”210(从不多或少)连续数字后,计算出错误信息。 发生了什么??

最佳答案

我对 server.cpp 做了一些改动。首先在构造函数上重新配置 acceptor_。删除了 while 循环,添加了 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;
}

我想,默认接受器一次可以 async_accept 200 个连接事件。您打开一个套接字,然后在无限循环中从客户端关闭它。结果,您打开和关闭一个连接 200 次,但它仍然是 1 个连接,1 个套接字。

通过调用 listen(1) 将其上限设置为 1,将强制接受器触发一个事件。您增加计数,然后客户端关闭连接。这样您就可以正确计算每个连接事件。

最后一点:异步 io 使用 1 个线程来处理连接事件、检索数据等...因此,不需要使用互斥量。

关于c++ - 神秘的200连接从何而来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5256449/

相关文章:

c++ - [文字游戏]Quiddler Solver Algorithm

c++ - boost asio SSL 服务器错误 : called a function you should not call

C++ Boost asio 获取数据大小?

c++ - 如何使用从 on_read 处理程序调度的最终回调将响应异步返回给调用者?

c++ - 使用 const-cast 通过非常量引用来延长临时的生命周期

c++ - 从串行到 omp : no speedup

c++ - boost:asio 线程池实现,用于偶尔同步的任务

c++ - asio::streambuf 到 std::istream 丢弃新行

c++ - 递归函数中的变量在每次调用中都采用相同的内存地址吗?

c++ - 重载派生类的赋值运算符的正确方法是什么?