我正在尝试使用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]).
答案 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.
希望这会有所帮助:)