导读:本期聚焦于闲进程创作的《Node.js如何实现arp扫描与Mock2Image图片模拟功能?》,敬请观看详情。局域网设备探测怎么做?arp协议通过IP地址反查MAC地址,是网络管理中最基础也最实用的手段。本文用Node.js原生net与dgram能力结合系统arp命令,实现IP段批量扫描、设备在线检测,并在扫描结果基础上完成arp数据的Mock模拟,把扫描到的设备信息渲染成占位图片,方便在无真实设备的环境下做前端联调与测试。文中包含完整的扫描代码、Mock数据生成方案以及图片输出实现,同时对Windows与Linux下的命令差异做了对比说明,适合需要在局域网场景做设备发现或接口模拟的开发者参考。

在局域网开发场景中,经常需要知道当前网段内有哪些设备在线,比如智能家居调试、内网设备管理面板等。arp协议正好承担了这个职责:它通过IP与MAC地址的映射关系,让我们可以快速探测局域网内的存活设备。本文将使用Node.js实现arp扫描功能,并结合Mock2Image思路,把扫描结果转成可视化的模拟图片输出,方便前端联调时直接使用。

Node.js如何实现arp扫描与Mock2Image图片模拟功能?

arp协议基础与Node.js调用方式

arp(Address Resolution Protocol,地址解析协议)工作在网络层与数据链路层之间,负责把IP地址解析成MAC地址。当一台主机需要和同网段另一台主机通信时,会先发送arp请求广播,目标设备收到后回复自己的MAC地址,双方再将映射关系缓存到本地arp表中。

在Node.js中我们并不需要从零构造arp报文,直接读取操作系统的arp缓存表即可。Windows下可以使用arp -a命令,Linux下则可以读取/proc/net/arp文件或执行同样的命令。Node.js的child_process.exec模块可以很方便地执行系统命令并拿到输出结果。

const { exec } = require('child_process');

function getArpTable() {
  return new Promise((resolve, reject) => {
    exec('arp -a', { encoding: 'utf8' }, (err, stdout) => {
      if (err) return reject(err);
      resolve(stdout);
    });
  });
}

getArpTable().then(table => {
  console.log(table);
});

上面这段代码在Windows与Linux下都能运行,区别在于输出格式不同。Windows输出为表格形式,Linux输出为多行文本。因此解析时需要做兼容处理,这也是下面实现解析器时要重点解决的问题。

实现arp扫描与解析

单纯读取arp缓存只能拿到最近通信过的设备,如果需要扫描整个网段,可以先对每个IP发起一次轻量连接(比如TCP连接网关或常见端口),触发系统写入arp缓存,然后再统一解析缓存表。下面给出完整实现。

const net = require('net');
const { exec } = require('child_process');

// 触发arp记录:尝试与目标IP的80端口建立TCP连接
function touchHost(ip) {
  return new Promise(resolve => {
    const socket = new net.Socket();
    socket.setTimeout(800);
    socket.once('connect', () => { socket.destroy(); resolve(true); });
    socket.once('timeout', () => { socket.destroy(); resolve(false); });
    socket.once('error', () => { socket.destroy(); resolve(false); });
    socket.connect(80, ip);
  });
}

// 解析arp -a 输出,兼容Windows和Linux
function parseArpOutput(output) {
  const devices = [];
  const lines = output.split('\n');
  for (const line of lines) {
    // 匹配 IP 和 MAC 地址
    const ipMac = line.match(/(\d{1,3}(?:\.\d{1,3}){3})\s+.*?([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})/);
    if (ipMac) {
      devices.push({ ip: ipMac[1], mac: ipMac[2].toLowerCase() });
    }
  }
  return devices;
}

// 扫描指定网段
async function scanSubnet(base, from, to) {
  for (let i = from; i <= to; i++) {
    await touchHost(`${base}.${i}`);
  }
  return new Promise((resolve, reject) => {
    exec('arp -a', { encoding: 'utf8' }, (err, stdout) => {
      if (err) return reject(err);
      resolve(parseArpOutput(stdout));
    });
  });
}

scanSubnet('192.168.1', 1, 254).then(devices => {
  console.log(`发现 ${devices.length} 台设备`);
  console.log(devices);
});

解析函数中使用的正则表达式同时兼容了Windows的短横线分隔MAC和Linux的冒号分隔MAC格式,匹配到后统一转成小写便于后续比较。需要注意的是,扫描是串行发起的,254个地址大约需要几十秒,如果追求速度可以用Promise.all并发执行,但要控制并发数量,避免瞬时创建过多socket拖垮系统。

另一个细节是超时时间的设置。800毫秒对于局域网已经足够,如果网络环境较差可以适当调大。判定设备在线的标准是它出现在arp表中,因为只要TCP握手发起,系统就会完成arp解析,即使端口未开放,arp记录同样会生成。

Mock2Image:把扫描结果渲染成占位图片

拿到设备列表后,下一步是Mock2Image的核心思路:把数据模拟成图片。这在前后端联调时特别有用,前端需要一个返回设备图片的接口,但真实设备可能不在线,此时可以直接用Node.js动态生成带有设备信息的PNG图片作为响应。

生成图片不依赖第三方库也可以做到,但手写PNG编码比较繁琐,推荐使用svg2png思路:先用SVG描述图片内容,再转成PNG。这里为了演示清晰,直接用HTTP接口返回SVG,大多数浏览器都支持直接渲染SVG图片。

const http = require('http');

function buildDeviceSvg(device) {
  const label = `${device.ip} / ${device.mac}`;
  return `<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200">
  <rect width="100%" height="100%" fill="#2d3436"/>
  <text x="200" y="90" font-size="20" fill="#dfe6e9" text-anchor="middle">Device Mock</text>
  <text x="200" y="130" font-size="16" fill="#74b9ff" text-anchor="middle">${label}</text>
</svg>`;
}

http.createServer((req, res) => {
  const device = { ip: '192.168.1.105', mac: 'aa:bb:cc:dd:ee:ff' };
  res.writeHead(200, { 'Content-Type': 'image/svg+xml' });
  res.end(buildDeviceSvg(device));
}).listen(3000, () => {
  console.log('Mock image server running at http://127.0.0.1:3000');
});

前端只需要把<img>标签的src指向这个接口地址,就能拿到一张带设备IP与MAC信息的模拟图片。如果确实需要PNG格式,可以引入sharp库把SVG转换成PNGBuffer后再输出,代码只需增加几行。

工程化建议与注意事项

把扫描和图片服务整合成一个完整工具时,建议注意以下几点。第一,arp命令需要系统权限正常执行,某些精简版Linux容器中可能没有arp命令,此时应改为直接读取/proc/net/arp文件。第二,扫描结果建议加缓存,避免每次请求都触发全网段扫描,可以设置一个TTL,比如60秒内复用上次结果。

第三,如果这个服务会暴露给外部访问,一定要做IP白名单限制,因为arp表暴露了内网设备信息,属于敏感数据。第四,在Mock场景下可以预置一批虚拟设备数据,扫描不到真实设备时自动降级到Mock数据,保证前端页面始终有内容可渲染,这也是Mock2Image方案最大的价值所在:环境无关、开箱即用。

整套方案代码量不大,核心难点只在arp输出的兼容解析和扫描触发机制上。理解了这两点,就可以根据实际业务扩展出设备指纹识别、上下线告警等更复杂的功能。

Node.jsarp扫描Mock2Image修改时间:2026-08-31 04:00:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。