18
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2022

Day 14

Elixir :inetモジュールのインターネット関連の関数

Last updated at Posted at 2022-12-07

Erlanginetモジュールにインターネット関連の関数があります。いくつか挙げてみます。

:inet.ip_address型

ErlangではIPアドレスは整数のTupleとして扱われるようです。

IPv4の例
{10, 0, 0, 202}
IPv6の例
{65152, 0, 0, 0, 47655, 60415, 65227, 8746}

:inet.ntoa/1

:inet.ip_address型のIPアドレスを、IPv4またはIPv6アドレス文字列に変換します。
文字列と言ってもErlangの文字列ElixirでいうCharlistです。

IEx IPv4の例
iex> :inet.ntoa({10, 0, 0, 202})
'10.0.0.202'
IEx IPv6の例
iex> :inet.ntoa({65152, 0, 0, 0, 47655, 60415, 65227, 8746})
'fe80::ba27:ebff:fecb:222a'

:inet.gethostbyname/1

指定されたホスト名を持つホストのhostentレコードを返します。

IEx IPv4の例
iex> :inet.gethostbyname('elixir-lang.org')
{:ok,
 {:hostent, 'elixir-lang.org', [], :inet, 4,
  [
    {185, 199, 108, 153},
    {185, 199, 111, 153},
    {185, 199, 110, 153},
    {185, 199, 109, 153}
  ]}}
IEx IPv6の例
iex> :inet.gethostbyname('elixir-lang.org', :inet6)
{:ok,
 {:hostent, 'elixir-lang.org',
  ['elixir-lang.org', 'elixir-lang.org', 'elixir-lang.org'], :inet6, 16,
  [
    {9734, 20672, 32768, 0, 0, 0, 0, 339},
    {9734, 20672, 32771, 0, 0, 0, 0, 339},
    {9734, 20672, 32769, 0, 0, 0, 0, 339},
    {9734, 20672, 32770, 0, 0, 0, 0, 339}
  ]}}

:inet.port/1

  • ソケットのポート番号を返します。
IEx
iex> {:ok, socket} = :gen_tcp.listen(0, [])
{:ok, #Port<0.6>}

iex> {:ok, port_number} = :inet.port(socket)
{:ok, 56106}

iex> :gen_tcp.close(socket)
:ok

:inet.sockname/1という似たような関数もあります。

IEx
iex> {:ok, {ip_address, port_number}} = :inet.sockname(socket)
{:ok, {{0, 0, 0, 0}, 56114}}

:inet.info/1

ソケットに関するさまざまな情報を返します。

IEx
iex> :inet.info(socket)
%{
  counters: %{
    recv_avg: 0,
    recv_cnt: 0,
    recv_dvi: 0,
    recv_max: 0,
    recv_oct: 0,
    send_avg: 0,
    send_cnt: 0,
    send_max: 0,
    send_oct: 0,
    send_pend: 0
  },
  input: 0,
  links: [#PID<0.111.0>],
  memory: 40,
  monitors: [],
  output: 0,
  owner: #PID<0.111.0>,
  states: [:listen, :open]
}

:inet.getifaddrs/0

  • インターフェイス名とインターフェイスのアドレスを含む2要素のTupleのリストを返します。
IEx
iex(15)> {:ok, if_list} = :inet.getifaddrs()
{:ok,
 [
   {
    # インターフェイス名
    'lo0',
    # インターフェイスのアドレス
    [
      flags: [:up, :loopback, :running, :multicast],
      addr: {127, 0, 0, 1},
      netmask: {255, 0, 0, 0},
      addr: {0, 0, 0, 0, 0, 0, 0, 1},
      netmask: {65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535},
      addr: {65152, 0, 0, 0, 0, 0, 0, 1},
      netmask: {65535, 65535, 65535, 65535, 0, 0, 0, 0}
    ]},
    ...
 ]}

inetsモジュール

inetモジュールと名前が似ているのでややこしいですが、)inetsモジュールは、起動や停止など、:inetsアプリケーションを操作する基本的なAPIを提供するそうです。

Elixirのソースコードにも1箇所出てきます。 何をやっているのかよく理解していませんが、HTTPクライアントのhttpcを使う前に:inetsアプリケーションを起動して、使った後に停止しているように見えます。

  defp read_httpc(path) do
    {:ok, _} = Application.ensure_all_started(:ssl)
    {:ok, _} = Application.ensure_all_started(:inets)

    # Starting an HTTP client profile allows us to scope
    # the effects of using an HTTP proxy to this function
    {:ok, _pid} = :inets.start(:httpc, profile: :mix)

    ...

    try do
      case httpc_request(request, http_options) do
        {:error, {:failed_connect, [{:to_address, _}, {inet, _, reason}]}}
        when inet in [:inet, :inet6] and
               reason in [:ehostunreach, :enetunreach, :eprotonosupport, :nxdomain] ->
          :httpc.set_options([ipfamily: fallback(inet)], :mix)
          request |> httpc_request(http_options) |> httpc_response()

        response ->
          httpc_response(response)
      end
    after
      Logger.configure(level: level)
      :inets.stop(:httpc, :mix)
    end
  end

ご参考までに

18
1
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
18
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?