Erlang:查找我的IP地址

Erlang:查找我的IP地址,erlang,Erlang,我正在尝试使用Redis为某些部分完成负载平衡器/登录服务器/游戏服务器设置。负载平衡就是其中之一。在我的Redis负载平衡实例中,我使用的是有序集。关键是应用程序名,成员是游戏服务器的IP地址 这就是我的问题所在。我想在erlang中使用公共方法。我找不到任何适合我需要的东西。我想知道我是不是看过头了 {ok, L} = inet:getif(), IP = element(1, hd(L)), 给了我想要的东西。我相信现在是{192168,0,14}。但该功能不是“公共的” 给我{0,0,

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

这就是我的问题所在。我想在erlang中使用公共方法。我找不到任何适合我需要的东西。我想知道我是不是看过头了

{ok, L} = inet:getif(),
IP = element(1, hd(L)),
给了我想要的东西。我相信现在是{192168,0,14}。但该功能不是“公共的”

给我{0,0,0,0}。我尝试了
inet:getaddr(“owl”)
,它给出了{127,0,1,1}

我是否仅限于通过TCP和使用
inet:peername(Socket)
发送消息?这么简单的东西似乎太多了。我的应用程序的所有不同部分都运行在同一台计算机上进行测试。它会把{127,0,0,1}还给我吗?那不行。我需要将IP发送回用户(我的手机),以便他们可以连接到适当的服务器。环回是不行的

当前代码

我要感谢所有的答复。是的,我注意到Lol4t0在新年刚过时的评论。所以我修改了代码以反映这一点。为像我这样的慢性子发这篇文章。我得绞尽脑汁让这些东西按一下

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

hd([Addr |{{},Opts}您应该首先了解您的主机可以有多个唯一的IP地址。事实上,所有
{0,0,0}
{127,0,0,1}
(嘿!实际上所有127.0.0.0/8都是您的地址)和
{192168,0,14}
是您所有的有效IP地址。此外,如果您的主机连接了其他一些接口,您将获得更多的IP地址。因此,您基本上找不到一个函数来获取您需要的IP地址

相反,它在
inet
模块中有很好的文档记录,该模块将列出每个具有自己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()]

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

local_ip_v4() ->
    {ok, Addrs} = inet:getifaddrs(),
    hd([
         Addr || {_, Opts} <- Addrs, {addr, Addr} <- Opts,
         size(Addr) == 4, Addr =/= {127,0,0,1}
    ]).
local\u ip\u v4()->
{ok,Addrs}=inet:getifaddrs(),
高清([
使用getifaddr()的Addr |{|,Opts}来自OTP的函数提供了机器可用的所有接口的详细列表。以下解决方案应该可以清除许多对erlang感到困惑的新手,因为它也难倒了我。此函数未经优化,但可读性很强,可以为您的机器提供本地IP4地址,就像您在LAN聚会上使用的地址一样:

 %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.

希望这有帮助:)

谢谢。应该一直在在线erlang手册页上查找列表。我知道每个接口都有一个IP:)我只需要一个唯一的有效接口即可使用(即没有任何环回)因此,我的手机可以与它通话,游戏服务器实例可以适当限制速率。这符合要求。我曾研究过PropList,但这是我的首选。我对以这种方式构建列表不太熟悉。谢谢。我对其进行了轻微修改。也许你会更喜欢它。:)发生在我身上的是,它正在抢夺下一个(ipv6)环回…虽然如果我使用您的大小限制,它不会发生。hd([Addr | |{if,Opts}@NolanRobidoux可以随机为您提供IPv4和IPv6,它不考虑名称为
lo0
等的接口。我想不管怎样,使用它总会有一些调整。对我来说,如果我使用IPv4或IPv6,只要我的手机可以与我的计算机通信。@NolanRobidoux,“发生在我身上的是,它抓住了下一个(ipv6)环回”你只需要检查标志,而不是应用黑客。
 %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.