I'm using boost::asio for network communication and I'm wondering why in the examples sometimes the socket.connect(endpoint)
and some other times the boost::asio::connect(socket, endpoint)
is used. According to the code boost::asio::connect
is calling the socket.connect
in a loop for endpoint iterators. So my question is:
Which is better behaviour? Using boost::asio::connect or socket.connect? Personaly I prefer the socket.connect, because I have just one endpoint. Or may I'm wrong and misunderstood the asio libs.
Also my second question is, why the endpoint is an iterator? How can it be possible, more then one connections when 1 ip and 1 port is given?
Also there is a boost::asio::write and socket.write...
The examples are:
Boost. Asio is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach. Overview. An overview of the features included in Boost. Asio, plus rationale and design information.
The io_service class provides the core I/O functionality for users of the asynchronous I/O objects, including: boost::asio::ip::tcp::socket. boost::asio::ip::tcp::acceptor.
boost::asio::connect()
is a higher level free function that will invoke boost::asio::ip::tcp::socket::connect()
. The documentation is fairly clear here
This function attempts to connect a socket to one of a sequence of endpoints. It does this by repeated calls to the socket's connect member function, once for each endpoint in the sequence, until a connection is successfully established.
Neither has better behavior, though that is largely a subjective term. It's up to you and your application how you want to handle connection establishment. If you need to provide some sort of feedback to the user, ex: "attempting to connect to host 1 of 10"
it might be preferable to use socket.connect()
in a loop rather than the connect()
free function.
The connect()
free function takes an endpoint iterator so it can connect to all possible endpoints that are resolved. The tcp echo client that you linked to does this
tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), argv[1], argv[2]);
tcp::resolver::iterator iterator = resolver.resolve(query);
tcp::socket s(io_service);
boost::asio::connect(s, iterator);
Why the endpoint is an iterator?
A query (tcp::resolver::query) with 1 ip and 1 port has only one endpoint, but the parameters of query may contain URL:
boost::asio::ip::tcp::resolver::query query("www.baidu.com", "http");
Query can obtain several ip address of baidu.com, as the code shown:
boost::asio::ip::tcp::resolver::query query1("www.baidu.com", "http");
boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query1);
boost::asio::ip::tcp::resolver::iterator end;
while (iter != end)
{
boost::asio::ip::tcp::endpoint endpoint = *iter++;
std::cout << endpoint << std::endl;
}
Output:
180.97.33.108:80
180.97.33.107:80
In the example of daytime.1:
tcp::resolver::query query(argv[1], "daytime");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
Now we create and connect the socket. The list of endpoints obtained above may contain both IPv4 and IPv6 endpoints, so we need to try each of them until we find one that works. This keeps the client program independent of a specific IP version.
The Query may contain several endpoints, boost::asio::connect() can automatically connect one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With