我的网络中的设备/计算机发现

时间:2014-06-26 14:47:00

标签: node.js

我正在尝试为我的测试项目编写一个示例程序,以找出所有设备(如android或IOS)或连接到我的计算机所连接的网络的其他计算机。 当我登录路由器管理控制台时,我能够看到所有连接的设备,并且我希望使用我的程序获得相同的列表。 我尝试了下面的示例代码,我在https://gist.github.com/chrishulbert/895382发现了帖子并发现它很有趣并尝试使用它,但我无法获得列表。我在下面的代码中遗漏了一些东西,或者这是我所指的错误样本?在这方面,我们将非常感谢任何帮助。

function listen(port) {
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) 
    {
  console.log("server got: " + msg + " from " + rinfo.address + ":" + rinfo.port);
});
server.bind(port); 

}

function search() {
var message = new Buffer(
    "M-SEARCH * HTTP/1.1\r\n" +
    "HOST:239.255.255.250:1900\r\n" +
    "MAN:\"ssdp:discover\"\r\n" +
    "ST:ssdp:all\r\n" + 
    "MX:3\r\n" + 
    "\r\n"
);

var client = dgram.createSocket("udp4");
client.bind(0,"",function() {
    console.log(client.address().port);
    listen(client.address().port);
    client.send(message, 0, message.length, 1900, "239.255.255.250",
                function()     {
        // client.close();
    });
}); // So that we get a port so we can listen before sending

}
search();

3 个答案:

答案 0 :(得分:2)

@Algi,设备发现的最佳选择是使用需要提升权限的ICMP协议。使用UDP协议(在OSI层3& 4中运行)不适合设备发现,除非实现用于发现的现有客户端/服务器协议,例如与DNS,NetBIOS和DropBox应用程序一起使用的协议)。

请不要误解可以在这些更高级别的协议上实现设备发现,但假设设备不存在于网络上,因为UDP / TCP端口N未打开是愚蠢的。

@Josh3736所述,可以实施SSDP,但由于使用了UPnP,我建议不要使用该文章中列出的原因。

@Illizian,我是node-libnmap软件包的作者,并且想知道您是否可以详细说明它是什么时候"不可靠"。你用的是哪个版本?最新修订版为0.1.10,非常稳定。

因为它与nmap二进制文件接口,所以你的扫描结果可能会受到--min-rt-timeout, - max-rt-timeout& --initial-rt-timeout选项,用于实现"空闲扫描实现算法"成分(S)。

这些组件将根据之前的探测时间动态设置超时,如果扫描过度过滤(基于主机和基于周边的IDS和IPS系统),那么您肯定会得到意想不到的结果。

话虽如此,如果你遇到的问题超出了那个范围,你可能发现了一个错误?如果是这样,请在https://github.com/jas-/node-libnmap/issues报告?

在旁注上使用arp表来发现附近的主机不会提供" all"您网段上的可用主机。只有那些" chatty"当时。 arp表不断地推动/弹出桌子上的机器。

答案 1 :(得分:1)

我在Unix系统上使用nmap来获取网络上的设备列表。存在用于与nmap(npm link | github)交互的NodeJS库;所以你应该能够使用以下代码获得IP列表:

require('node-libnmap').nmap('discover', function(err, report){
    if (err) throw err
    console.log(report)
});

您将看到以下输出:

{
    adapter: 'eth0',
    properties: {
        address: '10.0.2.15',
        netmask: '255.255.255.0',
        family: 'IPv4',
        mac: '52:54:00:12:34:56',
        internal: false,
        cidr: '10.0.2.0/24',
        hosts: 256,
        range: { start: '10.0.2.1', end: '10.0.2.254' }
    },
    neighbors: [ '10.0.2.2', '10.0.2.3', '10.0.2.15' ]
}

希望有所帮助:)

更新:我发现nmap有点不可靠,并在node-arp library中找到了替代方案,以下代码段输出了从/proc/net/arp文件解析的IP和Mac地址数组:

var fs = require('fs');

fs.readFile('/proc/net/arp', function(err, data) {
    if (!!err) return done(err, null);

    var output = [];
    var devices = data.toString().split('\n');
    devices.splice(0,1);

    for (i = 0; i < devices.length; i++) {
        var cols = devices[i].replace(/ [ ]*/g, ' ').split(' ');

        if ((cols.length > 3) && (cols[0].length !== 0) && (cols[3].length !== 0) && cols[3] !== '00:00:00:00:00:00') {
            output.push({
                ip: cols[0],
                mac: cols[3]
            });
        }
    }

    console.log(output);
});

答案 2 :(得分:0)

您使用的代码是SSDP的一个非常基本的实现。 (如果您想使用SSDP,则有more complete modules。)

您遇到的问题是其他设备必须积极参与SSDP发现过程。这意味着他们必须侦听您发送的数据包并回复它们。在大多数默认配置中不会发生这种情况;因此你没有得到任何结果。

您的路由器的管理页面能够显示设备列表,因为它是DHCP服务器。您的路由器负责为网络上的每台设备分配IP地址,因此它了解大多数设备。 (您可以使用静态IP地址配置设备,设备可能不会显示在路由器列表中。)

简单的方法就是刮掉路由器的管理页面。如果您很幸运,您的路由器将通过API公开此信息。否则,使用request从路由器的管理面板获取地址分配页面,并使用cheerio解析HTML。