boost::asio::ip::address を使ってipアドレスを変換する

More than 1 year has passed since last update.

目的

コマンドライン引数より入力した dotted decimal形式のipv4アドレス
例:192.168.1.2
を、バイト配列に変換しようと思いました

もちろん .でsplitして自力で分解しても良いのですが
asioの機能を使うべきでしょう
それには boost::asio::ip::address_v4 を使えば良いようです

http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/ip__address_v4.html

ここが Referenceです

ところが上手くいかなかった

コンストラクタは、default constructor、バイト配列、long値、コピーコンストラクタ
のみで、dotted decimal文字列からは構築出来ないので
default constructorで構築し、from_string で設定し
to_xxx で変換

方針は決まったので早速 コーディング

address_v4
  boost::asio::ip::address_v4 ipp;
  ipp.from_string("192.168.1.2");
  std::cout << "to_string()  " << ipp.to_string() << std::endl;
  std::cout << "to_ulong()  " << ipp.to_ulong() << std::endl;
  auto bt(ipp.to_bytes());
  std::cout << "to_bytes()  " << (int)bt[0] << "." << (int)bt[1] << "." << (int)bt[2] << "." << (int)bt[3]  << std::endl;



実行結果
to_string()  0.0.0.0
to_ulong()  0
to_bytes()  0.0.0.0

・・・ あれ?? ダメじゃん

ip::address_v4 を調べる

仕方ないので コードを調べます
引数が const char*、const char*, error_code&、 const string&、 const string&, error_code
と4つオーバーライドがありますが どれも同じなので

address_v4.hpp
  /// Create an address from an IP address string in dotted decimal form.
  BOOST_ASIO_DECL static address_v4 from_string(const char* str);
address_v4.ipp
address_v4 address_v4::from_string(const char* str)
{
  boost::system::error_code ec;
  address_v4 addr = from_string(str, ec);
  boost::asio::detail::throw_error(ec);
  return addr;
}

ん??? staticメソッド。
from_stringは factoryパターンのようです

完成版

ということで、factoryパターンに対応させます

address_v4
  auto ipp = boost::asio::ip::address_v4::from_string("192.168.1.2");
  std::cout << "to_string()  " << ipp.to_string() << std::endl;
  std::cout << "to_ulong()  " << ipp.to_ulong() << std::endl;
  auto bt(ipp.to_bytes());
  std::cout << "to_bytes()  " << (int)bt[0] << "." << (int)bt[1] << "." << (int)bt[2] << "." << (int)bt[3]  << std::endl;



実行結果
to_string()  192.168.1.2
to_ulong()  3232235778
to_bytes()  192.168.1.2

うまくいきましたね。

悩み

from_string()の戻りは この場合一時オブジェクトになり 右辺値参照になるんでしたっけ?
なので
auto ipp = std::move(boost::asio::ip::address_v4::from_string("192.168.1.2"));
とは 書いていないけど どうだっけ・・

あと、今回は代入演算子で行っているが コピーコンストラクタの方が良いのか?

あるいは 参照で受け取るのか

イマイチ 右辺値参照を本格的に理解していないので
疑問は残ったので
もっと勉強が必要だ