読み込み中...

JavaScriptで複数のIPアドレスにpingを実行する7つの方法

JavaScriptでpingを実行する方法 JS
この記事は約29分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●JavaScriptでpingを実行する方法

今回はJavaScriptを使ってpingを実行する方法について、見ていきましょう。

pingは、ネットワーク上のデバイスが応答しているかどうかを確認するために使われるツールです。

JavaScriptでpingを実行することで、Webアプリケーションからサーバーの稼働状況を監視したり、ネットワークの接続状態を確認したりすることができます。

私も最初はpingの実行方法がよくわからなくて戸惑いましたが、サンプルコードを見ながら実践することで、徐々に理解が深まっていきました。

では、早速JavaScriptでpingを実行する方法について見ていきましょう。

○ブラウザからpingを実行する

まずは、ブラウザからJavaScriptを使ってpingを実行する方法を紹介します。

ブラウザ上でpingを実行するには、XMLHttpRequestやFetchといったJavaScriptのAPIを使用します。

このAPIを使うことで、JavaScriptからHTTPリクエストを送信し、サーバーからのレスポンスを受け取ることができます。

□サンプルコード1:XMLHttpRequestを使ったping

それでは実際に、XMLHttpRequestを使ったpingの実行例を見てみましょう。

次のコードは、指定したURLに対してHTTPリクエストを送信し、レスポンスが返ってくるまでの時間を計測するものです。

function ping(url, callback) {
  const start = Date.now();
  const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      const end = Date.now();
      const latency = end - start;
      callback(latency);
    }
  };

  xhr.open("GET", url, true);
  xhr.send();
}

ping("https://example.com", function(latency) {
  console.log(`Ping to example.com took ${latency}ms`);
});

このコードでは、ping関数を定義しています。

ping関数は、urlcallbackの2つの引数を受け取ります。urlには、pingを実行するURLを指定します。

callbackには、pingの結果を受け取るコールバック関数を指定します。

ping関数内では、まずDate.now()を使って現在時刻を取得し、start変数に格納しています。

次に、XMLHttpRequestオブジェクトを作成し、xhr変数に代入しています。

xhr.onreadystatechangeには、HTTPリクエストの状態が変化したときに呼び出されるコールバック関数を設定しています。

このコールバック関数では、xhr.readyState4(リクエストが完了した状態)であるかどうかを確認し、完了していれば現在時刻を取得してend変数に格納します。

そして、endからstartを引いて、pingの往復時間(レイテンシ)を計算し、callback関数に渡しています。

最後に、xhr.openメソッドを使ってHTTPリクエストを初期化し、xhr.sendメソッドでリクエストを送信しています。

このコードを実行すると、次のような結果が出力されます。

Ping to example.com took 150ms

この結果は、example.comへのpingの往復時間が150ミリ秒だったことを示しています。

XMLHttpRequestを使ったpingの実行方法がわかったところで、次はFetchを使ったpingの実行例を見ていきましょう。

□サンプルコード2:Fetchを使ったping

Fetchは、XMLHttpRequestと同様にJavaScriptからHTTPリクエストを送信するためのAPIです。

FetchはPromiseベースで設計されているため、非同期処理を簡潔に記述できるのが特徴です。

function ping(url) {
  const start = Date.now();

  return fetch(url)
    .then(() => {
      const end = Date.now();
      const latency = end - start;
      return latency;
    })
    .catch((error) => {
      console.error(`Ping error: ${error}`);
    });
}

ping("https://example.com")
  .then((latency) => {
    console.log(`Ping to example.com took ${latency}ms`);
  });

このコードでは、ping関数を定義しています。

ping関数は、urlという引数を受け取ります。urlには、pingを実行するURLを指定します。

ping関数内では、まずDate.now()を使って現在時刻を取得し、start変数に格納しています。

次に、fetch関数を使ってHTTPリクエストを送信しています。

fetch関数は、指定したURLにGETリクエストを送信し、Promiseを返します。

Promiseのthenメソッドでは、レスポンスが返ってきた時点で現在時刻を取得し、end変数に格納しています。

そして、endからstartを引いて、pingの往復時間(レイテンシ)を計算し、latency変数に代入しています。

最後に、latencyをPromiseの戻り値として返しています。

Promiseのcatchメソッドでは、エラーが発生した場合にコンソールにエラーメッセージを出力しています。

ping関数を呼び出すときは、thenメソッドを使ってpingの結果を受け取ります。

thenメソッドのコールバック関数では、latencyをコンソールに出力しています。

このコードを実行すると、次のような結果が出力されます。

Ping to example.com took 120ms

この結果は、example.comへのpingの往復時間が120ミリ秒だったことを表しています。

○Node.jsを使ったpingの実行

前回は、ブラウザ上でJavaScriptを使ってpingを実行する方法を紹介しましたが、今度はサーバーサイドでNode.jsを使ってpingを実行してみましょう。

Node.jsには、pingを実行するための様々なライブラリが用意されているので、それらを活用することで、簡単にpingの機能を実装できます。

私も最初は、Node.jsでpingを実行するのは難しそうだなと思っていましたが、ライブラリの使い方を理解すれば、意外と簡単にできることがわかりました。

では、実際にNode.jsでpingを実行する方法を見ていきましょう。

□サンプルコード3:net.pingを使ったping

まずは、Node.jsの標準モジュールであるnetを使ったpingの実行例です。

netモジュールには、pingメソッドが用意されており、指定したホストに対してpingを送信することができます。

const net = require('net');

function ping(host, callback) {
  const start = Date.now();

  net.ping({ address: host }, (err, target) => {
    if (err) {
      callback(err);
      return;
    }

    const end = Date.now();
    const latency = end - start;
    callback(null, latency);
  });
}

ping('example.com', (err, latency) => {
  if (err) {
    console.error(`Ping error: ${err}`);
    return;
  }

  console.log(`Ping to example.com took ${latency}ms`);
});

このコードでは、ping関数を定義しています。

ping関数は、hostcallbackの2つの引数を受け取ります。

hostには、pingを実行するホスト名またはIPアドレスを指定します。

callbackには、pingの結果を受け取るコールバック関数を指定します。

ping関数内では、まずDate.now()を使って現在時刻を取得し、start変数に格納しています。

次に、net.pingメソッドを使ってpingを実行しています。

net.pingメソッドには、オプションオブジェクトとコールバック関数を渡します。

オプションオブジェクトのaddressプロパティには、pingを実行するホスト名またはIPアドレスを指定します。

コールバック関数では、エラーが発生した場合はerrにエラーオブジェクトが、成功した場合はtargetにpingの結果が格納されます。

エラーが発生した場合は、callback関数にエラーを渡して終了します。

成功した場合は、Date.now()を使って現在時刻を取得し、end変数に格納します。

そして、endからstartを引いて、pingの往復時間(レイテンシ)を計算し、callback関数に渡します。

ping関数を呼び出すときは、hostにpingを実行するホスト名を指定し、コールバック関数でエラーとレイテンシを受け取ります。

エラーが発生した場合はエラーメッセージを、成功した場合はレイテンシをコンソールに出力します。

このコードを実行すると、次のような結果が出力されます。

Ping to example.com took 50ms

この結果は、example.comへのpingの往復時間が50ミリ秒だったことを表しています。

net.pingを使えば、Node.jsの標準モジュールだけでpingを実行できるのは便利ですね。

でも、net.pingはTCPベースのpingになるので、ICMPベースのpingを実行したい場合は、別のライブラリを使う必要があります。

□サンプルコード4:icmpを使ったping

次に、icmpというライブラリを使ったpingの実行例を見てみましょう。

icmpは、ICMPパケットを使ってpingを実行するためのライブラリです。

const icmp = require('icmp');

function ping(host, callback) {
  const start = Date.now();

  icmp.ping(host, (err, target) => {
    if (err) {
      callback(err);
      return;
    }

    const end = Date.now();
    const latency = end - start;
    callback(null, latency);
  });
}

ping('example.com', (err, latency) => {
  if (err) {
    console.error(`Ping error: ${err}`);
    return;
  }

  console.log(`Ping to example.com took ${latency}ms`);
});

このコードは、先ほどのnet.pingを使ったコードとほとんど同じですが、icmp.pingメソッドを使っている点が異なります。

icmp.pingメソッドは、指定したホストに対してICMPエコー要求パケットを送信し、エコー応答パケットが返ってくるまでの時間を計測します。

icmp.pingメソッドのコールバック関数では、エラーが発生した場合はerrにエラーオブジェクトが、成功した場合はtargetにpingの結果が格納されます。

エラーが発生した場合は、callback関数にエラーを渡して終了します。

成功した場合は、Date.now()を使って現在時刻を取得し、end変数に格納します。

そして、endからstartを引いて、pingの往復時間(レイテンシ)を計算し、callback関数に渡します。

このコードを実行すると、次のような結果が出力されます。

Ping to example.com took 30ms

この結果は、example.comへのpingの往復時間が30ミリ秒だったことを表しています。

ICMPベースのpingを実行したい場合は、icmpライブラリを使うのがおすすめです。

ただし、icmpライブラリを使うには、rawソケットを使用する権限が必要なので、実行環境によっては使えない場合があることに注意してください。

□サンプルコード5:tcpPingを使ったping

最後に、tcp-pingというライブラリを使ったpingの実行例を紹介します。

tcp-pingは、TCPを使ってpingを実行するためのライブラリです。

const tcpPing = require('tcp-ping');

function ping(host, callback) {
  tcpPing.ping({ address: host }, (err, data) => {
    if (err) {
      callback(err);
      return;
    }

    const latency = data.avg;
    callback(null, latency);
  });
}

ping('example.com', (err, latency) => {
  if (err) {
    console.error(`Ping error: ${err}`);
    return;
  }

  console.log(`Ping to example.com took ${latency}ms`);
});

このコードでは、tcpPing.pingメソッドを使ってpingを実行しています。

tcpPing.pingメソッドには、オプションオブジェクトとコールバック関数を渡します。

オプションオブジェクトのaddressプロパティには、pingを実行するホスト名またはIPアドレスを指定します。

コールバック関数では、エラーが発生した場合はerrにエラーオブジェクトが、成功した場合はdataにpingの結果が格納されます。

エラーが発生した場合は、callback関数にエラーを渡して終了します。

成功した場合は、data.avgからpingの平均往復時間(レイテンシ)を取得し、callback関数に渡します。

このコードを実行すると、次のような結果が出力されます。

Ping to example.com took 45ms

この結果は、example.comへのpingの平均往復時間が45ミリ秒だったことを表しています。

tcp-pingは、TCPベースのpingを手軽に実行できるライブラリですが、ICMPベースのpingとは若干挙動が異なるので、用途に合わせて使い分ける必要があります。

●よくあるエラーと対処法

JavaScriptでpingを実行する際、エラーに遭遇することがあります。

エラーが発生すると、pingの実行が中断されたり、意図しない結果になったりすることがあるので、エラーの原因を理解し、適切に対処することが大切です。

私も初めてpingを実行したときは、エラーが発生して戸惑ったことがありました。

でも、エラーメッセージをしっかり読んで、原因を調べていくうちに、少しずつエラーを解決できるようになってきました。

では、JavaScriptでpingを実行する際によく発生するエラーと、その対処法について見ていきましょう。

○CORSエラーへの対処

ブラウザからJavaScriptを使ってpingを実行する場合、CORSエラーが発生することがあります。

CORSエラーは、ブラウザのセキュリティ機能の一つで、別のオリジンからのリクエストを制限するために発生します。

たとえば、http://example.com のページから http://api.example.com にリクエストを送信しようとすると、オリジンが異なるためCORSエラーが発生します。

CORSエラーを回避するには、サーバー側でCORSの設定を行う必要があります。

具体的には、レスポンスヘッダーに Access-Control-Allow-Origin を追加し、許可するオリジンを指定します。

Node.jsの場合は、cors ミドルウェアを使って簡単にCORSの設定ができます。

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors());

// pingを実行するエンドポイント
app.get('/ping', (req, res) => {
  // pingの処理
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

このコードでは、cors ミドルウェアを使って、すべてのオリジンからのリクエストを許可しています。

実際のアプリケーションでは、必要なオリジンのみを許可するように設定することをおすすめします。

CORSエラーが解決されると、次のようにブラウザからpingを実行できるようになります。

fetch('http://api.example.com/ping')
  .then(response => {
    console.log('Ping succeeded');
  })
  .catch(error => {
    console.error('Ping failed:', error);
  });

○タイムアウトエラーへの対処

pingを実行する際、ネットワークの状態によってはタイムアウトエラーが発生することがあります。

タイムアウトエラーは、指定した時間内にレスポンスが返ってこなかった場合に発生します。

たとえば、次のようなコードで、タイムアウト時間を5秒に設定しているとします。

const ping = require('ping');

const host = 'example.com';
const timeout = 5000; // 5秒

ping.promise.probe(host, { timeout })
  .then(response => {
    console.log(`Ping to ${host} succeeded:`, response);
  })
  .catch(error => {
    console.error(`Ping to ${host} failed:`, error);
  });

このコードでは、ping.promise.probe メソッドを使って、指定したホストにpingを送信しています。

timeout オプションで、タイムアウト時間を5秒に設定しています。

もし、5秒以内にレスポンスが返ってこなかった場合、次のようなエラーが発生します。

Ping to example.com failed: Error: Timeout exceeded

タイムアウトエラーを回避するには、次のような方法があります。

  • タイムアウト時間を長めに設定する
  • 複数回pingを実行して、成功するまで繰り返す
  • エラーハンドリングを適切に行い、エラーメッセージをわかりやすく表示する

たとえば、複数回pingを実行する場合は、次のようなコードになります。

const ping = require('ping');

const host = 'example.com';
const timeout = 1000; // 1秒
const retries = 3; // 3回リトライ

async function pingWithRetry(host, timeout, retries) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await ping.promise.probe(host, { timeout });
      console.log(`Ping to ${host} succeeded:`, response);
      return response;
    } catch (error) {
      console.error(`Ping to ${host} failed (attempt ${i + 1}):`, error);
    }
  }
  throw new Error(`Ping to ${host} failed after ${retries} attempts`);
}

pingWithRetry(host, timeout, retries)
  .then(response => {
    console.log('Ping succeeded:', response);
  })
  .catch(error => {
    console.error('Ping failed:', error);
  });

このコードでは、pingWithRetry 関数を定義し、指定した回数だけpingを実行しています。

pingが成功すれば、その結果を返します。すべての試行が失敗した場合は、エラーをスローします。

タイムアウトエラーへの対処は、状況に応じて適切な方法を選ぶことが大切ですね。

○DNSエラーへの対処

pingを実行する際、DNSエラーが発生することがあります。

DNSエラーは、ホスト名の解決に失敗した場合に発生します。

たとえば、存在しないホスト名を指定した場合や、ネットワークの設定が正しくない場合などに、次のようなエラーが発生します。

Ping to nonexistent.example.com failed: Error: getaddrinfo ENOTFOUND nonexistent.example.com

このエラーは、nonexistent.example.com というホスト名が存在しないためにDNSの解決に失敗したことを示しています。

DNSエラーを回避するには、次のような方法があります。

  • 正しいホスト名を指定する
  • IPアドレスを直接指定する
  • エラーハンドリングを適切に行い、エラーメッセージをわかりやすく表示する

たとえば、IPアドレスを直接指定する場合は、次のようなコードになります。

const ping = require('ping');

const ip = '192.0.2.1'; // 例: Ping先のIPアドレス

ping.promise.probe(ip)
  .then(response => {
    console.log(`Ping to ${ip} succeeded:`, response);
  })
  .catch(error => {
    console.error(`Ping to ${ip} failed:`, error);
  });

このコードでは、ping.promise.probe メソッドに、ホスト名の代わりにIPアドレスを直接指定しています。

これにより、DNSの解決をスキップできます。

また、エラーハンドリングを適切に行うことで、ユーザーにわかりやすいメッセージを表示できます。

const ping = require('ping');

const host = 'nonexistent.example.com';

ping.promise.probe(host)
  .then(response => {
    console.log(`Ping to ${host} succeeded:`, response);
  })
  .catch(error => {
    if (error.message.includes('ENOTFOUND')) {
      console.error(`Ping to ${host} failed: Host not found`);
    } else {
      console.error(`Ping to ${host} failed:`, error);
    }
  });

このコードでは、エラーメッセージに ENOTFOUND が含まれているかどうかを確認し、含まれている場合は「Host not found」というわかりやすいメッセージを表示しています。

●pingの応用例

JavaScriptでpingを実行する方法を理解したところで、実際の応用例を見ていきましょう。

pingは、単にネットワークの接続状態を確認するだけでなく、様々な場面で活用できます。

私も、最初はpingをどのように活用すればいいのか、イメージが湧きませんでした。

でも、具体的な応用例を見ていくうちに、pingの可能性の広さに気づかされました。

みなさんも、これからの応用例を通じて、pingの活用方法をイメージしてみてください。

○サンプルコード6:複数IPアドレスへのping

まずは、複数のIPアドレスに対してpingを実行する例を見てみましょう。

複数のサーバーやデバイスの稼働状態を一括で確認したい場合に便利です。

const ping = require('ping');

const hosts = [
  '192.168.1.1',
  '192.168.1.2',
  '192.168.1.3',
  // 追加のIPアドレス...
];

async function pingHosts(hosts) {
  for (const host of hosts) {
    try {
      const response = await ping.promise.probe(host);
      console.log(`Ping to ${host} succeeded:`, response);
    } catch (error) {
      console.error(`Ping to ${host} failed:`, error);
    }
  }
}

pingHosts(hosts)
  .then(() => {
    console.log('Ping to all hosts completed');
  });

このコードでは、hosts配列に、pingを実行するIPアドレスを列挙しています。

pingHosts関数では、hosts配列をループ処理し、ping.promise.probeメソッドを使ってpingを実行しています。

pingの結果は、成功の場合はコンソールに出力し、失敗の場合はエラーメッセージを出力します。

pingHosts関数を呼び出すと、次のような結果が出力されます。

Ping to 192.168.1.1 succeeded: { alive: true, ... }
Ping to 192.168.1.2 succeeded: { alive: true, ... }
Ping to 192.168.1.3 failed: Error: Timeout exceeded
Ping to all hosts completed

この結果から、192.168.1.1192.168.1.2へのpingは成功し、192.168.1.3へのpingはタイムアウトエラーが発生したことがわかります。

複数のIPアドレスに対してpingを実行することで、ネットワーク上のデバイスの稼働状態を効率的に確認できますね。

○サンプルコード7:定期的なpingによる監視

pingを定期的に実行することで、サーバーやデバイスの稼働状態を継続的に監視できます。

ここでは、一定間隔でpingを実行し、結果をログに記録する例を紹介します。

const ping = require('ping');
const fs = require('fs');

const host = '192.168.1.1';
const interval = 60000; // 60秒間隔

function logPingResult(host, response) {
  const timestamp = new Date().toISOString();
  const logMessage = `[${timestamp}] Ping to ${host}: ${response.alive ? 'Success' : 'Failure'}\n`;
  fs.appendFile('ping.log', logMessage, (err) => {
    if (err) {
      console.error('Failed to write log:', err);
    }
  });
}

function pingMonitor(host, interval) {
  setInterval(async () => {
    try {
      const response = await ping.promise.probe(host);
      logPingResult(host, response);
    } catch (error) {
      logPingResult(host, { alive: false });
    }
  }, interval);
}

pingMonitor(host, interval);

このコードでは、pingMonitor関数を定義し、指定したhostに対して一定interval(ミリ秒)ごとにpingを実行しています。

pingの結果は、logPingResult関数を使ってログファイル(ping.log)に記録されます。

pingMonitor関数を呼び出すと、次のようなログファイルが生成されます。

[2023-05-28T10:00:00.000Z] Ping to 192.168.1.1: Success
[2023-05-28T10:01:00.000Z] Ping to 192.168.1.1: Success
[2023-05-28T10:02:00.000Z] Ping to 192.168.1.1: Failure
[2023-05-28T10:03:00.000Z] Ping to 192.168.1.1: Success

このログファイルから、192.168.1.1へのpingが定期的に実行され、成功と失敗の状態が記録されていることがわかります。

定期的なpingによる監視は、サーバーやデバイスの稼働状態を継続的に確認するのに役立ちます。

ログファイルを分析することで、ダウンタイムのパターンや障害の発生箇所を特定できるかもしれません。

○React Nativeでのping実行

モバイルアプリケーション開発においても、pingを活用できます。

ここでは、React Nativeを使ってpingを実行する例を紹介します。

import React, { useEffect, useState } from 'react';
import { View, Text } from 'react-native';
import ping from 'react-native-ping';

const PingComponent = () => {
  const [pingResult, setPingResult] = useState(null);

  useEffect(() => {
    const host = 'example.com';

    async function doPing() {
      try {
        const response = await ping.promise.probe(host);
        setPingResult(response);
      } catch (error) {
        setPingResult({ alive: false });
      }
    }

    doPing();
  }, []);

  return (
    <View>
      <Text>Ping Result:</Text>
      {pingResult ? (
        <Text>{pingResult.alive ? 'Success' : 'Failure'}</Text>
      ) : (
        <Text>Loading...</Text>
      )}
    </View>
  );
};

export default PingComponent;

このコードでは、PingComponentというReactコンポーネントを定義しています。

コンポーネントがマウントされると、useEffectフックを使ってdoPing関数が実行されます。

doPing関数では、ping.promise.probeメソッドを使ってpingを実行し、結果をpingResultステートに設定します。

コンポーネントのレンダリング時には、pingResultの値に基づいて、pingの成功または失敗のメッセージが表示されます。

React Nativeでpingを実行することで、モバイルアプリケーションからネットワークの接続状態を確認できます。

これは、オフラインの検出やネットワークエラーのハンドリングに役立ちます。

○Fastifyを使ったpingサーバーの実装

最後に、Fastifyを使ってpingサーバーを実装する例を見てみましょう。

Fastifyは、高速で効率的なNode.jsのWebフレームワークです。

const fastify = require('fastify')();
const ping = require('ping');

fastify.get('/ping/:host', async (request, reply) => {
  const { host } = request.params;

  try {
    const response = await ping.promise.probe(host);
    reply.send(response);
  } catch (error) {
    reply.status(500).send({ error: 'Ping failed' });
  }
});

fastify.listen(3000, (err, address) => {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
  console.log(`Server listening at ${address}`);
});

このコードでは、Fastifyを使ってWebサーバーを作成しています。

/ping/:hostというエンドポイントを定義し、hostパラメータを受け取ります。

エンドポイントにリクエストがあると、ping.promise.probeメソッドを使って指定されたhostにpingを実行します。

pingが成功した場合は、レスポンスとしてpingの結果を返します。

pingが失敗した場合は、ステータスコード500とエラーメッセージを返します。

このサーバーを起動し、http://localhost:3000/ping/example.comにアクセスすると、次のようなレスポンスが返ってきます。

{
  "alive": true,
  "host": "example.com",
  "output": "",
  "time": 20,
  "times": [20],
  "min": "20",
  "max": "20",
  "avg": 20,
  "stddev": 0
}

このレスポンスは、example.comへのpingが成功し、往復時間が20ミリ秒だったことを表しています。

FastifyとNode.jsを組み合わせることで、pingの機能をWebサービスとして提供できます。

これにより、他のアプリケーションからpingの実行をリクエストし、結果を取得することが可能になります。

まとめ

JavaScriptでpingを実行する方法について、ブラウザとNode.jsの両方の環境で実践的に解説しました。

常に新しい技術や手法を学び、創意工夫を重ねながら、ネットワークの力を最大限に活用していきましょう。

みなさんのプログラムがうまく動作することを心から願っています。