npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rust-ping

v1.1.0

Published

High-performance ICMP ping for Node.js/Bun — single-socket concurrent ping, zero child processes, powered by Rust napi-rs

Readme

English | 中文

rust-ping

高性能 ICMP Ping 模块,基于 Rust 实现,适用于 Node.js / Bun。

单 socket 多路复用架构 —— 100 个并发 ping 共享 1 个 ICMP socket,无需 spawn 子进程。

特性

  • 🚀 高性能 — Rust 原生实现,单 socket + 单 recv 线程,零进程开销,空闲自动回收线程和 socket
  • 🔀 真并发 — 100 个并发 ping ≈ 几百毫秒(对比 node-ping 的 100 个子进程 ≈ 几十秒)
  • 📦 多种调用方式 — Callback / Promise / Batch,按需选择
  • 🎯 开箱即用 — 预编译二进制分发,无需 node-gyp,无需本地编译环境
  • 🔌 Node-API (N-API) — ABI 稳定,不受 Node.js 版本升级影响,可直接用于 Electron / NW.js 等运行时,无需针对不同版本重新编译
  • 🌐 支持域名 — 自动 DNS 解析,直接 ping 域名
  • 🧭 IPv4 / IPv6 选择 — 通过 protocol: 'ipv4' | 'ipv6' 按 session 指定协议
  • ⏱️ 超时重试 — 可配置超时时间和重试次数
  • 💻 跨平台 — Windows 7+、macOS 10.12+、Linux (glibc 2.17+ / musl)

安装

npm install rust-ping

快速开始

ESM:

import { session } from 'rust-ping';

const result = await session.ping('baidu.com');
console.log(result);
// { host: 'baidu.com', addr: '110.242.68.66', alive: true, time: 28.5, ttl: 52, bytes: 72, seq: 1 }

CommonJS:

const { session } = require('rust-ping');

const result = await session.ping('baidu.com');
console.log(result);

开箱即用,无需手动创建/关闭 session。内部自动管理 ICMP socket 生命周期(空闲 10 秒自动释放)。

用法

方式一:默认 session(推荐)

导入即用,内部懒加载创建 ICMP socket,空闲后自动关闭,下次调用自动重建。适合大多数场景。

import { session } from 'rust-ping';

// 直接 ping,首次调用时自动创建底层 session
const result = await session.ping('8.8.8.8');
console.log(result.time); // RTT (ms)

// 并发多目标
const results = await session.pingBatch(['8.8.8.8', '1.1.1.1', '114.114.114.114']);

配置(setConfig

默认 session 使用 setConfig 修改参数。仅在 session 未激活时可调用(首次 ping 之前,或 close/keepAlive 回收之后):

import { session } from 'rust-ping';

// 首次 ping 前配置
session.setConfig({
  protocol: 'ipv4',  // 'ipv4' 或 'ipv6',默认 'ipv4'
  timeout: 5000,     // 单次超时(ms),默认 2000
  retries: 2,        // 超时重试次数,默认 1
  keepAlive: 30000,  // 空闲存活时间(ms),默认 10000,0 表示不自动关闭
});

await session.ping('8.8.8.8'); // 用上述参数创建 session

session 激活后调用 setConfig 会抛错,需要先 close()

await session.ping('8.8.8.8');         // session 已激活

session.setConfig({ timeout: 1000 });  // ❌ Error: Cannot setConfig while session is active.

session.close();                       // 手动关闭
session.setConfig({ timeout: 1000 });  // ✅ 可以了
await session.ping('8.8.8.8');         // 用新参数自动重建

生命周期

首次 ping() → 自动创建 socket + recv 线程
           → 后续 ping 复用同一 socket
           → 空闲 keepAlive 时间后自动关闭(释放线程和 socket)
下次 ping() → 自动重建

也可以手动关闭:

session.close(); // 立即关闭,释放资源。之后可 setConfig + 再次使用

方式二:createSession(自定义实例)

需要多个不同配置的 session,或需要完全控制生命周期时使用。必须手动调用 close() 释放资源。

import { createSession } from 'rust-ping';

const session = createSession({
  protocol: 'ipv4',
  timeout: 5000,
  retries: 2,
  ttl: 64,
  packetSize: 32,
});

const result = await session.ping('8.8.8.8');
console.log(result);

// 用完必须关闭!否则 recv 线程和 socket 不会释放
session.close();

适用场景:

  • 需要同时存在多个 session(不同超时、不同 TTL)
  • 需要精确控制 socket 何时创建/销毁
  • 长期运行的服务中需要避免自动重建的开销
// 多实例并存
import { createSession } from 'rust-ping';

const fast = createSession({ timeout: 500, retries: 0 });
const slow = createSession({ timeout: 10000, retries: 3 });
const ipv6 = createSession({ protocol: 'ipv6' });

await fast.ping('127.0.0.1');    // 快速探测
await slow.ping('10.0.0.1');     // 慢速重试
await ipv6.ping('::1');          // IPv6 会话

fast.close();
slow.close();
ipv6.close();

protocol 是 session 级配置。'ipv4' 用于 IPv4 目标和 DNS A 记录,'ipv6' 用于 IPv6 目标和 DNS AAAA 记录。默认值是 'ipv4'。一个 session 只处理一种协议;如果同时需要 IPv4 和 IPv6,请分别创建 session。


API 详细

createSession(options?)

创建自定义 session。每个 session 持有一个 raw ICMP socket,使用完需要手动关闭。

const ipv4 = createSession({ protocol: 'ipv4' });
const ipv6 = createSession({ protocol: 'ipv6' });

ipv4.close();
ipv6.close();

配置项:

| 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | protocol | 'ipv4' \| 'ipv6' | 'ipv4' | 当前 session 使用的 IP 协议。IPv4 DNS 只选 A 记录,IPv6 DNS 只选 AAAA 记录。 | | timeout | number | 2000 | 单次 ping 超时时间,单位 ms。 | | retries | number | 1 | 超时后的重试次数。 | | ttl | number | 128 | IP TTL / hop limit。 | | packetSize | number | 64 | ICMP payload 大小,单位 bytes。 |

如果把 IPv6 目标传给 IPv4 session,或把 IPv4 目标传给 IPv6 session,会得到明确的无效地址错误。

session.ping(target, opts?)

Promise 风格单次/多次 ping。

// 单次
const result = await session.ping('8.8.8.8');
// { host, addr, alive, time, ttl, bytes, seq }

// 多次(返回统计)
const stats = await session.ping('8.8.8.8', { count: 5 });
// { host, alive, min, max, avg, packetLoss, replies, errors }

session.pingBatch(targets, opts?)

并发 ping 多个目标,返回 Map<string, PingResult>

const results = await session.pingBatch(['8.8.8.8', '1.1.1.1']);
for (const [target, result] of results) {
  console.log(`${target}: ${result.alive ? result.time + 'ms' : 'dead'}`);
}

session.pingHost(target, callback)

Callback 风格(兼容 net-ping)。

session.pingHost('8.8.8.8', (error, target, sent, rcvd) => {
  if (error) {
    console.log(`${target}: ${error.message}`);
  } else {
    console.log(`${target}: alive, RTT=${rcvd - sent}ms`);
  }
});

session.close()

关闭 session,释放 socket 和 recv 线程。关闭后所有 pending 请求会被 reject。


错误处理

import { session, PingTimeoutError, DestinationUnreachableError } from 'rust-ping';

try {
  await session.ping('10.255.255.1');
} catch (err) {
  if (err instanceof PingTimeoutError) {
    console.log('超时:', err.target);
  } else if (err instanceof DestinationUnreachableError) {
    console.log('不可达:', err.target, err.icmpType, err.icmpCode);
  }
}

| 错误类 | 含义 | |--------|------| | PingTimeoutError | 超时(含重试耗尽) | | DestinationUnreachableError | ICMP 目标不可达 |

并发性能

单 socket 多路复用的核心优势:100 个并发 ping 的总耗时 ≈ 最慢的那一个,而非逐个累加。

实测数据(Windows 10, 有线网络):

=== 并发 10 个不同目标 ===

  8.8.8.8           47.64ms
  8.8.4.4           47.56ms
  baidu.com         44.70ms
  208.67.222.222    44.63ms
  9.9.9.9           44.59ms
  127.0.0.1          0.01ms
  223.5.5.5         12.59ms
  119.29.29.29      36.77ms
  google.com        51.52ms
  github.com         8.64ms
  总耗时: 63ms          ← 不是累加的 348ms,而是 ≈ 最慢的 51ms

=== 并发 100 个 ping (google.com) ===

  成功: 100/100
  RTT min/avg/max: 44.87 / 47.02 / 51.62ms
  总耗时: 73ms          ← 100 次 × 47ms = 4700ms?不,只要 73ms

架构对比:

| 方案 | 100 次并发 | 总耗时 | 资源占用 | |------|-----------|--------|---------| | node-ping(spawn 子进程) | 串行排队或 100 个进程 | ~30 秒 | 100 个进程 ~50MB | | rust-ping(单 socket) | 真并发,共享 1 个 socket | ~73ms | 1 个线程 ~几百 KB |

平台支持

| 平台 | 最低版本 | 架构 | 权限要求 | |------|---------|------|---------| | Windows | 7 / Server 2008 R2+ | x64 | 管理员权限 | | macOS | 10.12 Sierra+ | x64 (Intel), ARM64 (Apple Silicon) | Root (sudo) | | Linux (glibc) | glibc 2.17+ (CentOS 7+) | x64, ARM64 | Root 或 CAP_NET_RAW | | Linux (musl) | Alpine 3.12+ | x64 | Root 或 CAP_NET_RAW |

权限说明: rust-ping 在所有平台使用原始 ICMP socket (SOCK_RAW) 以保证 identifier 匹配可靠,需要提升权限:

sudo node app.js

TypeScript

自带类型定义,无需安装 @types

import { session, createSession, PingTimeoutError } from 'rust-ping';

const result = await session.ping('8.8.8.8');

const ipv6 = createSession({ protocol: 'ipv6' });
await ipv6.ping('::1');
ipv6.close();

License

MIT