Erlang:找到我的IP地址

时间:2015-10-07 05:08:57

标签: erlang

我正在尝试使用Redis为某些部分完成Load Balancer / Login Server / Game Server设置。负载平衡就是其中之一。在我的Redis负载平衡实例中,我正在使用有序集。关键是应用程序名称,成员是游戏服务器的IP地址。

这就是我的问题。我想在erlang中使用一个公共方法。我找不到符合我需求的东西。我想知道我是不是在寻找一些东西。

{ok, L} = inet:getif(),
IP = element(1, hd(L)),

给我我正在寻找的东西。我相信目前是{192,168,0,14}。但这个功能不是“公开的”。

{ok, Socket} = gen_tcp:listen(?PORT_LISTEN_GAME, [{active,once}, {reuseaddr, true}]),
{ok, {IP, _} = inet:sockname(Socket),

给我{0,0,0,0}。我试过inet:getaddr("owl")给了我{127,0,1,1}。

我是否仅限于通过TCP发送邮件并使用inet:peername(Socket)?看起来很像是为了让事情变得如此简单。我的应用程序的所有不同部分都在同一台计算机上运行以进行测试。是否会让我回到{127,0,0,1}?那不行。我需要将IP发送回用户(我的手机),以便他们可以与正确的服务器连接。环回不会...... [/ p>

当前代码

我要感谢所有回复。是的,我注意到Lol4t0在新年之后的评论。所以我改变了我的代码来反映这一点。为像我这样的慢人发布这个。为了让这些东西可以点击,我不得不扯开我的大脑。

hd([Addr || {_, Opts} <- Addrs,
    {addr, Addr} <- Opts,
    {flags, Flags} <- Opts,
    lists:member(loopback,Flags) =/= true]).

3 个答案:

答案 0 :(得分:6)

我们已成功使用此功能获取第一个非本地IPv4地址:

local_ip_v4() ->
    {ok, Addrs} = inet:getifaddrs(),
    hd([
         Addr || {_, Opts} <- Addrs, {addr, Addr} <- Opts,
         size(Addr) == 4, Addr =/= {127,0,0,1}
    ]).

如果你想要的话,它当然可以改为返回IPv6。

答案 1 :(得分:2)

您应该首先了解您的主机可以拥有多个唯一的IP地址。事实上,所有{0,0,0,0}{127,0,0,1}(嘿!实际上所有127.0.0.0/8都是您的地址)和{192,168,0,14}都是您有效的IP地址。此外,如果您的主机将连接其他一些接口,您将获得更多的IP地址。因此,您基本上无法找到能够获得所需 IP地址的功能。

而是inet模块中记录良好的function,它将列出每个都有自己IP地址的接口:

getifaddrs() -> {ok, Iflist} | {error, posix()}

Types:

Iflist = [{Ifname, [Ifopt]}]
Ifname = string()
Ifopt = {flag, [Flag]}
      | {addr, Addr}
      | {netmask, Netmask}
      | {broadaddr, Broadaddr}
      | {dstaddr, Dstaddr}
      | {hwaddr, Hwaddr}
Flag = up
     | broadcast
     | loopback
     | pointtopoint
     | running
     | multicast
Addr = Netmask = Broadaddr = Dstaddr = ip_address()
Hwaddr = [byte()]

答案 2 :(得分:0)

使用OTP中的getifaddr()函数可提供该机器可用的所有接口的详细列表。下面的解决方案应该使很多困惑的新人感到困惑,因为它也使我感到困惑。此功能尚未优化,但可读性很强,可为您的计算机提供本地IP4地址,就像您在LAN派对上使用的IP4地址一样:

 %Get the local IP4 address of this machine in the local network (LAN party address)
local_ip_v4() ->
  {ok, IntfList} = inet:getifaddrs(), %Get a list of all interfaces (Wifi, Lan, Internal loopback etc)

  %Filter this list to look for an interface that is "up and running" (has a connection) 
   SelectedInf = lists:foldl( fun(El, SelectedIf)->
                {InfName,InfOpts} = El,
                Flags = lists:keyfind(flags,1,InfOpts),
                case Flags of
                  {flags,[up,running]} ->
                    {InfName,InfOpts};
                  _->
                    SelectedIf
                end
                end,
                none,IntfList),

  io:format("~n INTERFACES: ~p ",[IntfList]),
  io:format("~n Selected INTERFACE: ~p ",[SelectedInf]),

  %Look through this interface's properties for the addresses, but only match one
  % that has 4 components in the tuple!
  {Sel_InfName,Sel_InfOpts} = SelectedInf,
  Address_I4 = lists:foldl( fun(El,Addr)->
                              case El of
                                {addr,{A,B,C,D}}->
                                  {A,B,C,D};
                                _->
                                  Addr
                              end
                            end, none, Sel_InfOpts),
  io:format("~n Selected INTERFACE IP4: ~p ~n",[Address_I4]),
  Address_I4.

希望这会有所帮助:)