denn
denn

Reputation: 355

boost::asio bind exception when binding a endpoint

I make a server using boost::asio. And I have a problem with binding to a endpoint. So, if I init an acceptor in a constructor:

Server::Server(QWidget *parent) : QDialog(parent), acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 5555))

and after use it:

void Dialog::start_accept()
{
sockets.push_back(socket_ptr(new boost::asio::ip::tcp::socket(io_service)));
acceptor.async_accept(*(sockets[sockets.size() - 1]), boost::bind(&Server::handle_accept, this, sockets[sockets.size() - 1], _1));
}

it works fine. Server::handle_accept calls when a new client is connecting. But I want to connect to an arbitrary endpoint. And I add binding to this endpoint. Acceptor is a class member. sockets is an array of shared_ptr to asio sockets. If I add just:

void Server::start_accept()
{
sockets.push_back(socket_ptr(new boost::asio::ip::tcp::socket(io_service)));
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 4444);
acceptor.bind(endpoint);
acceptor.async_accept(*(sockets[sockets.size() - 1]), boost::bind(&Dialog::handle_accept, this, sockets[sockets.size() - 1], _1));
}

I get exception Wrong argument. I try:

void Server::start_accept()
{
sockets.push_back(socket_ptr(new boost::asio::ip::tcp::socket(io_service)));
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 4444);
acceptor.close();
acceptor.open(endpoint.protocol());
acceptor.bind(endpoint);
acceptor.async_accept(*(sockets[sockets.size() - 1]), boost::bind(&Server::handle_accept, this, sockets[sockets.size() - 1], _1));
}

but I get the same. So, how can I reuse the acceptor to rebind to a new address? OS is Ubuntu 14.04.

Upvotes: 1

Views: 2772

Answers (1)

denn
denn

Reputation: 355

Finally I resolved the question. I delete the acceptor and create a new one. Now acceptor is boost::scoped_ptr acceptor.

try
{
    if (acceptor && acceptor->is_open())
    {
        acceptor->cancel();
        acceptor->close();
    }
    acceptor.reset(new boost::asio::ip::tcp::acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), arg1.toInt())));
    acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
}
catch (const boost::system::system_error& error)
{
    add_log("Error accepting");
}

Upvotes: 1

Related Questions