我可以在不使用外部服务的情况下在Chrome应用中获取我的IP地址吗?

时间:2014-12-17 19:47:48

标签: javascript sockets google-chrome google-chrome-app

我正在构建chrome app并通过chrome socket api创建 UDP套接字

有没有办法在不使用外部服务的情况下检索自己的 IP地址? 我所说的“自己的IP地址”:客户端服务器都在同一个网络上。 Chrome应用需要使用自己的本地IP地址来回复 UDP广播

实际上只有chrome socket API用于该用例。但遗憾的是,我只收到以下回调对象:Object {paused: false, persistent: false, socketId: 17},它错过了localAddress属性。根据{{​​3}},它是SocketInfo对象中的(可选)属性。这本质上就是我正在运行的代码:

chrome.sockets.udp.create({}, function(socketInfo){
    chrome.sockets.udp.getInfo(socketInfo.socketId, function (detailedInfo){
        ipAddress = detailedInfo.localAddress;
        console.debug(detailedInfo); // containts no `localAddress`
    });
});

由于documentation中没有特殊权限,我也不认为我遗漏了任何manifest-permissions。这就是我使用的:

"sockets": {
  "udp": {
    "send": "*",
    "bind": "*"
  }
}

当我使用 Python 时,我可以实现以下目标:

import socket
ip_address = socket.gethostbyname(socket.gethostname())

任何帮助都会很棒!

3 个答案:

答案 0 :(得分:4)

原来我一直在使用错误的API。对于我的用例,我需要使用chrome.system.network.getNetworkInterfaces

这将返回所有接口的数组及其 IP地址

这是我的示例代码:

chrome.system.network.getNetworkInterfaces(function(interfaces){
    console.log(interfaces);
});

清单的权限:

"permissions": [
  "system.network"
],

考虑到这些评论,不容易提供完美的解决方案,因为必须找到UDP端口的正确接口。

此时,完全匹配接口的唯一方法是bind给出的所有接口的getNetworkInterfaces所有地址。然后您确切地知道接收呼叫的确切接口,您可以使用正确的IP地址进行回复。

答案 1 :(得分:0)

未连接的套接字尚未拥有本地地址,除非它专门绑定到某个地址。一旦连接套接字(TCP)或通过套接字(UDP)发送数据,它只获取本地和远程地址。它只获取本地计算机的IP地址,而如果您在某些NAT路由器(即大多数家庭用户)后面,外部服务会看到路由器面向Internet的外部地址。

答案 2 :(得分:-1)

在最初创建套接字时调用您提供给udp.create()的回调,而不是在套接字接收数据包时调用。在创建时,套接字尚未与任何localAddresslocalPort相关联。您必须调用udp.bind()来建立套接字将侦听数据包的特定localPort(以及可选的特定localAddress)。如果您bind()"0.0.0.0",则套接字将侦听所有本地IP。

当新数据包到达时,会触发udp.onReceive事件。该数据包是由特定localAddress收到的,但Chrome API未提供直接查询哪个localAddress收到数据包的方法(基础recvfrom()套接字函数未提供该信息) 。要发现接收本地IP,您必须:

  1. 将套接字绑定到特定的localAddress,因为这将是唯一可以触发该套接字的onReceive事件的本地IP。

  2. 检查chrome.system.network.getNetworkInterfaces()报告的接口列表。如果报告1个接口,那将是接收所有数据包的接口,因此您可以使用其address。但是,如果报告了2个以上的接口,则必须从数据包的remoteAddress解析网络前缀,并将该值与每个报告的接口的前缀进行比较,直到找到匹配项(假设发送方正在从同一个网络广播)本地计算机连接到的网络子网,而不是跨子网边界进行广播。)

  3. 话虽如此,如果您需要将本地IP放入广播回复的数据有效负载中,所有这些都是相关的。假设有3个本地接口,并且在接口2上接收广播数据包。回复接口1或3的localAddress显然是错误的,因为它们位于与广播公司不同的网络上。但是,如果您不需要将localAddress放入回复的有效负载中,那么广播公司只需查看回复的remoteAddress即可知道您的IP地址是什么。然后您根本不需要弄清楚您的本地IP,当您将回复发送到您收到广播的remoteAddress / remotePort时,操作系统将为您处理所有内容。