如何在Node.js应用程序中进行“Ping”操作?

62

我想从我的node.js应用程序中ping一台服务器。

这可行吗?

谢谢


3
制作ICMP消息通常需要root权限,因此如果您正在Unix上运行,则您的脚本必须以suid root运行,但我不确定您是否希望这样做。或者,您需要能够启动一个外部进程(即ping),该进程具有suid root权限,我不知道在node.js中是否可能,但我认为应该是可能的。 - falstro
Nikolaus的方法可能会变慢,如果你经常这样做,因为你正在分叉进程(相对昂贵)。 - Alfred
7个回答

40

你可以使用exec来调用系统的ping命令。

var exec = require('child_process').exec;
exec("ping -c 3 localhost", function (err, stdout, stderr) {
    console.log(stdout);
});

15
你可以用这种方式做。但是如果你同时频繁地这样做,那么会变得很昂贵,因为分叉进程的成本相对较高。 - Alfred

27

node-net-ping 是一个非常棒的模块,它使用原始套接字。

而且,如果你只需要原始套接字,同样的开发者也有一个适用于此的模块:node-raw-socket


有没有想过如何使用node-net-ping来ping一个URL而不是IP地址?域名无法解析。 - Bach
1
这似乎不支持端口? - Oli Beatson
11
Ping是ICMP协议的一部分,该协议没有端口的概念。 - broofa
2
@Bach,你可以使用dns.resolve()自己解析域名。 - undefined
虽然有些晚了,但是作为谷歌搜索的第一个结果,我想再强调一下:您无法对端口进行ping测试,也无法对URL进行ping测试,原因相同。您只能ping测试IP地址。 - René Roth

10

我是ping-wrapper的作者。

它会自动启动ping进程,并且你可以立即监听事件。如果进程退出,它将自动重新启动。


如何安装这个? - Prafulla Kumar Sahu
1
使用npm。运行npm install --save ping-wrapper - mixdev

9

进行ping(可编程)需要root权限,因为它需要原始套接字,这需要root访问权限。您可以按照 Gradwohl's片段执行ping,但请记住,这将分叉一个新进程,这是昂贵的(相对而言)。如果您不需要频繁执行(并发),那么这肯定有效:)

在仅使用node.js的情况下执行此操作,我认为您有几个选项,这两个选项都很难实现:(

  1. ping python library 重写为node.js,并以root用户身份运行程序。
  2. 使用 asio c++库 为node.js编写c++扩展/插件。它还有一些关于如何进行icmp ping的示例。

不仅限于使用node.js:

  1. 使用Python ping库作为root运行,并通过redis与node.js实例通信。 => 最容易实现。(几乎没有什么工作,但我认为相当快 :))
  2. 再次编写c(++)代码,使用asio c++,但不是编写node.js扩展程序,而是通过hiredis与使用redis的node.js通信。

顺便提一下如何在node.js上使用redis:


3
你也可以使用我的Node.js ping包装器yaping。总有一天,我们会在Node.js中获得原始套接字,并能够制作自己的ping数据包并对响应时间进行伪造。;-)
这个简单的函数应该:
  • 进行DNS查找
  • ping一次
  • 10秒后超时
  • 传达所有良好考虑过的ping提供的错误代码
  • 非法地生成一个子进程

2

有几种方法可以做到这一点。最简单的方法是使用 ping 命令。您可以通过使用 child_process 模块来实现。

const { spawnSync } = require('child_process');
const os = require('os');

// Windows: ping -n 1 HOSTNAME
// Linux: ping -c 1 HOSTNAME

function pingHostname(hostname) {
   const result = spawnSync('ping', os.platform() === 'win32' ? ['-n', '1', hostname] : ['-c', '1', hostname]);
   return result.stdout.toString().includes('Reply from');
}

或者你可以使用net模块来ping一台服务器。

const net = require('net');

async function pingHostname(hostname) {
   return new Promise((resolve, reject) => {
      const socket = net.createConnection(80, hostname);
      socket.setTimeout(3000);
      socket.on('connect', () => {
         socket.end();
         resolve(true);
      });
      socket.on('timeout', () => {
         socket.destroy();
         resolve(false);
      });
      socket.on('error', () => {
         socket.destroy();
         resolve(false);
      });
   });
}

参考资料


0

它运行良好,

const { exec } = require("child_process");
exec("ping -c 10 google.com", (error, stdout, stderr) => {
    if (error) {
        console.log(`error: ${error.message}`);
        return;
    }
    if (stderr) {
        console.log(`stderr: ${stderr}`);
        return;
    }
    console.log(`stdout: ${stdout}`);
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接