14

私はネットワーク通信に boost::asio を使用していますが、なぜ例で が使用されsocket.connect(endpoint)たり、boost::asio::connect(socket, endpoint)が使用されたりするのか疑問に思っています。コードによると、エンドポイント イテレータのループ内で をboost::asio::connect呼び出しています。socket.connectだから私の質問は:

挙動が良いのはどっち?boost::asio::connect または socket.connect を使用していますか? 個人的には、エンドポイントが 1 つしかないため、socket.connect を好みます。または、私が間違っていて、asio libs を誤解している可能性があります。

また、私の 2 番目の質問は、なぜエンドポイントがイテレータなのかということです。1つのIPと1つのポートが指定されている場合、どうすれば複数の接続が可能になりますか?

また、boost::asio::write と socket.write... もあります。

例は次のとおりです。

  1. boost::asio::connect(ソケット、エンドポイント) blocks_tcp_echo_client.cpp .
  2. socket.connect(endpoint) (少し古いですが、まだ動作しています) Daytime.1
4

2 に答える 2

16

boost::asio::connect()を呼び出す上位レベルの自由関数ですboost::asio::ip::tcp::socket::connect()ドキュメントはここでかなり明確です

この関数は、一連のエンドポイントの 1 つにソケットを接続しようとします。これは、接続が正常に確立されるまで、シーケンス内のエンドポイントごとに 1 回、ソケットの connect メンバー関数を繰り返し呼び出すことによって行われます。

どちらもより良い動作はありませんが、それは主に主観的な用語です. 接続の確立をどのように処理するかは、ユーザーとアプリケーション次第です。ユーザーになんらかのフィードバックを提供する必要がある場合、例: free 関数よりもループで"attempting to connect to host 1 of 10"使用する方が望ましい場合があります。socket.connect()connect()

free 関数はconnect()エンドポイント イテレータを受け取るため、解決された可能性のあるすべてのエンドポイントに接続できます。リンクしたtcpエコークライアントはこれを行います

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) には 1 つのエンドポイントしかありませんが、クエリのパラメーターには 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 バージョンに依存しなくなります。

クエリには複数のエンドポイントが含まれる場合があり、boost::asio::connect() は自動的に 1 つを接続できます。

于 2016-11-17T04:44:42.130 に答える