在我的networking中的设备/计算机发现

我正在为我的testing项目编写一个示例程序,以找出连接到我的计算机所连接的networking的所有设备(如android或IOS)或其他计算机。 我能够看到所有连接的设备,当我login到路由器pipe理控制台,我想要使用我的程序相同的列表。 我尝试了下面的代码示例,我在https://gist.github.com/chrishulbert/895382发现了这个post,发现它很有趣,并试图使用它,但我无法获得列表。 我是否在下面的代码中丢失了一些东西,或者这是我指的错误的示例? 任何帮助将不胜感激在这方面。

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(); 

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

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

正如@Josh3736所提到的,SSDP可以实现,但是由于其使用UPnP,我会build议反对它,因为这篇文章中列出的原因。

@Illizian ,我是node-libnmap软件包的作者,想知道当你说它是不可靠的时候你是否可以详细说明。 你使用的是什么版本? 最新版本为0.1.10 ,相当稳定。

由于它与nmap二进制文件接口,扫描结果可能受到实现“空闲扫描实现algorithm”组件的–min-rt-timeout, – max-rt-timeout和–initial-rt-timeout选项的影响(S)。

这些组件将基于先前的探测时间dynamic地设置超时,如果扫描经严重过滤的(基于主机的和基于周边的IDS和IPS系统),那么您将最有可能得到意想不到的结果。

这就是说,如果你遇到了这个范围之外的问题,也许你find了一个错误? 如果可以的话,请在https://github.com/jas-/node-libnmap/issues报告。

在附注中使用arp表来发现附近的主机不会在你的网段上提供“所有”可用的主机。 只有那些当时“健谈”的人。 arp桌子不断地推动/popup机器离开桌子。

我在Unix系统上使用nmap来获取networking上的设备列表。 有一个用于与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库中find了一个替代scheme,下面的片段输出从/proc/net/arp文件parsing的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); }); 

你使用的代码是SSDP的一个非常基本的实现。 (如果你想使用SSDP,则有更完整的模块 。)

对您而言,问题是其他设备必须积极参与SSDP发现过程。 这意味着他们必须监听你发送的数据包并回复它们。 这在大多数默认configuration中不会发生。 因此你没有得到任何结果。

您的路由器的pipe理页面能够显示设备列表,因为它是DHCP服务器。 您的路由器负责将IP地址分配给您networking中的每个设备,因此它知道大多数设备。 (您可以使用静态IP地址configuration设备,设备可能不会显示在路由器列表中。)

简单的方法是只是刮你的路由器的pipe理页面。 如果幸运的话,路由器会通过API公开这些信息。 否则,请使用请求从路由器的pipe理面板获取地址分配页面,并使用cheerioparsingHTML。