Erlangのinetモジュールにインターネット関連の関数があります。いくつか挙げてみます。
: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
ご参考までに