14

我正在使用 boost::asio 进行网络通信,我想知道为什么在示例中有时使用 thesocket.connect(endpoint)和其他一些时间boost::asio::connect(socket, endpoint)。根据代码在循环中boost::asio::connect调用端点迭代器。socket.connect所以我的问题是:

哪个行为更好?使用 boost::asio::connect 或 socket.connect?就我个人而言,我更喜欢 socket.connect,因为我只有一个端点。或者我可能错了并且误解了 asio 库。

我的第二个问题是,为什么端点是迭代器?当给出 1 个 ip 和 1 个端口时,怎么可能有多个连接?

还有一个 boost::asio::write 和 socket.write...

这些例子是:

  1. boost::asio::connect(socket, endpoint) blocking_tcp_echo_client.cpp
  2. socket.connect(endpoint) (有点旧但仍在工作)Daytime.1
4

2 回答 2

16

boost::asio::connect()是一个更高级别的自由函数,它将调用boost::asio::ip::tcp::socket::connect(). 文档在这里相当清楚

此函数尝试将套接字连接到一系列端点中的一个。它通过重复调用套接字的连接成员函数来做到这一点,对序列中的每个端点一次,直到成功建立连接。

两者都没有更好的行为,尽管这在很大程度上是一个主观术语。如何处理连接建立取决于您和您的应用程序。如果您需要向用户提供某种反馈,例如:"attempting to connect to host 1 of 10"最好socket.connect()在循环中使用而不是在connect()自由函数中使用。

free 函数需要一个端点迭代器,connect()因此它可以连接到所有可能解析的端点。您链接到的 tcp echo 客户端执行此操作

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);
于 2013-03-28T16:58:40.870 回答
6

为什么端点是迭代器?

1 个 ip 和 1 个端口的查询(tcp::resolver::query)只有一个端点,但查询的参数可能包含 URL:

boost::asio::ip::tcp::resolver::query query("www.baidu.com", "http");  

查询可以获得baidu.com的多个ip地址,代码如下:

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;
}

输出:

180.97.33.108:80
180.97.33.107:80

----------

daytime.1的示例中:

tcp::resolver::query query(argv[1], "daytime");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

现在我们创建并连接套接字。上面获得的端点列表可能同时包含 IPv4 和 IPv6 端点,因此我们需要尝试每个端点,直到找到一个有效的端点。这使客户端程序独立于特定的 IP 版本。

Query 可能包含多个端点, boost::asio::connect() 可以自动连接一个。

于 2016-11-17T04:44:42.130 回答