web-dev-qa-db-ja.com

JavaScriptを使用してIPアドレスにpingを実行する方法

JavaScriptコードを実行して4つの異なるIPアドレスにpingを実行し、これらのping要求のパケット損失と遅延を取得してページに表示したいと思います。

どうすればよいですか?

9
user434885

JSからこれを行うことはできません。あなたができることはこれです:

 client --AJAX-- yourserver --ICMP ping-- targetservers

サーバーにAJAXリクエストを送信すると、ターゲットサーバーにpingが送信され、結果がAJAX結果になります。

考えられる警告:

  • これにより、ターゲットサーバーがユーザーのクライアントからではなくサーバーからping可能かどうかがわかります
    • そのため、クライアントはホストのLANをテストできなくなります
    • ただし、サーバーの内部ネットワークにホストが存在する場合は、ホストにホストをチェックさせないでください。
    • 一部のホストは特定のホストからのトラフィックをブロックし、他のホストはブロックしない場合があります
  • マシンごとのpingカウントを制限する必要があります:
    • AJAXリクエストのタイムアウトを回避するため
    • 一部のサイト運営者は、サイトに常にpingを送信し続けると、非常に腹を立てることがあります。
  • リソース
    • 長時間実行されるHTTPリクエストは、サーバーの最大接続制限に達する可能性があります。その高さを確認してください
    • 一度にpingを実行しようとする多くのユーザーは、疑わしいトラフィックを生成する可能性があります(すべてICMPのみ)
  • 同時実行性-少なくとも数秒間はアップ/ダウンステータスをプール/キャッシュして、同じターゲットにpingを実行したい複数のクライアントが大量のpingを起動しないようにすることができます。

私は最新のコメントに触発されたので、この簡単なコードを書きました。

これは一種の「HTTPping」であり、XMLHttpRequestcalls()と一緒に使用すると非常に便利だと思います。たとえば、場合によってはどのサーバーを使用するのが最速かを判断したり、ユーザーのインターネットから大まかな統計を収集したりできます。接続速度。

この小さな関数は、存在しないURL(404を返すことが予想される)でHTTPサーバーに接続し、サーバーがHTTP要求に応答するまでの時間を測定し、累積時間の平均を実行します。と反復回数。

要求されたURLは、呼び出しごとにランダムに変更されます。これは、(おそらく)一部の透過プロキシまたはキャッシュメカニズムで、場合によっては偽造が発生し、非常に高速な応答が得られることに気付いたためです(実際には、ICMPよりも高速です。

実際のHTTPサーバーに適合するFQDNを使用するように注意してください。結果は、IDが「result」のbody要素に表示されます。例:

<div id="result"></div>

機能コード:

function http_ping(fqdn) {

var NB_ITERATIONS = 4; // number of loop iterations
var MAX_ITERATIONS = 5; // beware: the number of simultaneous XMLHttpRequest is limited by the browser!
var TIME_PERIOD = 1000; // 1000 ms between each ping
var i = 0;
var over_flag = 0;
var time_cumul = 0;
var REQUEST_TIMEOUT = 9000;
var TIMEOUT_ERROR = 0;

document.getElementById('result').innerHTML = "HTTP ping for " + fqdn + "</br>";

var ping_loop = setInterval(function() {


        // let's change non-existent URL each time to avoid possible side effect with web proxy-cache software on the line
        url = "http://" + fqdn + "/a30Fkezt_77" + Math.random().toString(36).substring(7);

        if (i < MAX_ITERATIONS) {

            var ping = new XMLHttpRequest();

            i++;
            ping.seq = i;
            over_flag++;

            ping.date1 = Date.now();

            ping.timeout = REQUEST_TIMEOUT; // it could happen that the request takes a very long time

            ping.onreadystatechange = function() { // the request has returned something, let's log it (starting after the first one)

                if (ping.readyState == 4 && TIMEOUT_ERROR == 0) {

                    over_flag--;

                    if (ping.seq > 1) {
                        delta_time = Date.now() - ping.date1;
                        time_cumul += delta_time;
                        document.getElementById('result').innerHTML += "</br>http_seq=" + (ping.seq-1) + " time=" + delta_time + " ms</br>";
                    }
                }
            }


            ping.ontimeout = function() {
                TIMEOUT_ERROR = 1;
            }

            ping.open("GET", url, true);
            ping.send();

        }

        if ((i > NB_ITERATIONS) && (over_flag < 1)) { // all requests are passed and have returned

            clearInterval(ping_loop);
            var avg_time = Math.round(time_cumul / (i - 1));
            document.getElementById('result').innerHTML += "</br> Average ping latency on " + (i-1) + " iterations: " + avg_time + "ms </br>";

        }

        if (TIMEOUT_ERROR == 1) { // timeout: data cannot be accurate

            clearInterval(ping_loop);
            document.getElementById('result').innerHTML += "<br/> THERE WAS A TIMEOUT ERROR <br/>";
            return;

        }

    }, TIME_PERIOD);
}

たとえば、次のコマンドで起動します。

fp = new http_ping("www.linux.com.au"); 

HTTP応答時間は、ICMP応答時間からほぼ指数関数的であるように見えますが、このスクリプトの結果の数値と、対応する同じサーバー上のICMPpingとの間に単純な相関関係が見つからなかったことに注意してください。これは、HTTPリクエストを介して転送されるデータの量によって説明される可能性があります。これは、Webサーバーのフレーバーと構成、明らかにサーバー自体の速度、およびおそらく他の理由によって異なります。

これはあまり良いコードではありませんが、他の人を助け、おそらく刺激することができると思いました。

4
Gwen Wing

私が考えることができる唯一の方法は、例えば、ロードすることです。外部サーバーからの画像ファイル。そのロードが失敗すると、サーバーが応答していないことが「わかります」(サーバーがブロックしている可能性があるため、実際にはわかりません)。

このサンプルコードを見て、私が何を意味するかを確認してください。

 /*note that this is not an ICMP ping - but a simple HTTP request
    giving you an idea what you could do . In this simple implementation it has flaws
    as Piskvor correctly points out below */
    function ping(extServer){
     var ImageObject = new Image();
     ImageObject.src = "http://"+extServer+"/URL/to-a-known-image.jpg"; //e.g. logo -- mind the caching, maybe use a dynamic querystring
     if(ImageObject.height>0){
       alert("Ping worked!");
     } else {
       alert("Ping failed :(");
     }

}
4
Dennis G
function ping(url){
 new Image().src=url
}

上記のpingは、指定されたURLです。
一般的にカウンター/分析に使用されます。
client(javascript)への応答の失敗は発生しません

1
Dinesh

JSでpingを実行するのに最も近いのは、AJAXを使用し、readystates、status、およびheadersを取得することです。このようなもの:

url = "<whatever you want to ping>"
ping = new XMLHttpRequest();    
ping.onreadystatechange = function(){

    document.body.innerHTML += "</br>" + ping.readyState;

    if(ping.readyState == 4){
        if(ping.status == 200){
            result = ping.getAllResponseHeaders();
            document.body.innerHTML += "</br>" + result + "</br>";
        }
    }

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

もちろん、さまざまなhttpステータスの条件を設定し、説明などを使用して出力を好きなように表示して、見栄えを良くすることもできます。 pingよりもhttpurlステータスチェッカーの方が多いですが、実際には同じ考えです。いつでも数回ループして、pingのように感じることができます:)

1
Securis

Javascriptからサーバーにpingを実行することは可能ですか?

上記の解決策を確認する必要があります。かなり滑らか。

明らかに私のものではありませんが、それを明確にしたかったのです。

0
Jeffrey Tackett