listener(
        boost::asio::io_context& ioc,
        tcp::endpoint endpoint)
        : acceptor_(ioc)
        , socket_(ioc)
    {
        boost::system::error_code ec;

        // Open the acceptor
        acceptor_.open(endpoint.protocol(), ec);
        if(ec)
        {
            fail(ec, "open");
            return;
        }

        // Bind to the server address
        acceptor_.bind(endpoint, ec);
        if(ec)
        {
            fail(ec, "bind");
            return;
        }

        // Start listening for connections
        acceptor_.listen(
            boost::asio::socket_base::max_listen_connections, ec);
        if(ec)
        {
            fail(ec, "listen");
            return;
        }
    }
    listener(
        boost::asio::io_context& ioc,
        ssl::context& ctx,
        tcp::endpoint endpoint)
        : ctx_(ctx)
        , acceptor_(ioc)
        , socket_(ioc)
    {
        boost::system::error_code ec;

        // Open the acceptor
        acceptor_.open(endpoint.protocol(), ec);
        if(ec)
        {
            fail(ec, "open");
            return;
        }

        // Allow address reuse
        acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec);
        if(ec)
        {
            fail(ec, "set_option");
            return;
        }

        // Bind to the server address
        acceptor_.bind(endpoint, ec);
        if(ec)
        {
            fail(ec, "bind");
            return;
        }

        // Start listening for connections
        acceptor_.listen(
            boost::asio::socket_base::max_listen_connections, ec);
        if(ec)
        {
            fail(ec, "listen");
            return;
        }
    }
	peer_server()
		: m_peer_requests(0)
		, m_acceptor(m_ios)
		, m_port(0)
	{
		error_code ec;
		m_acceptor.open(tcp::v4(), ec);
		if (ec)
		{
			fprintf(stderr, "Error opening peer listen socket: %s\n", ec.message().c_str());
			return;
		}

		m_acceptor.bind(tcp::endpoint(address_v4::any(), 0), ec);
		if (ec)
		{
			fprintf(stderr, "Error binding peer socket to port 0: %s\n", ec.message().c_str());
			return;
		}
		m_port = m_acceptor.local_endpoint(ec).port();
		if (ec)
		{
			fprintf(stderr, "Error getting local endpoint of peer socket: %s\n", ec.message().c_str());
			return;
		}
		m_acceptor.listen(10, ec);
		if (ec)
		{
			fprintf(stderr, "Error listening on peer socket: %s\n", ec.message().c_str());
			return;
		}

		fprintf(stderr, "%s: peer initialized on port %d\n", time_now_string(), m_port);

		m_thread.reset(new thread(boost::bind(&peer_server::thread_fun, this)));
	}