LoginSignup
2
3

More than 5 years have passed since last update.

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

Posted at

目的

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

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

ここが 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"));
とは 書いていないけど どうだっけ・・

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

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

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

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3