如何使用 JavaScript ping IP 地址

发布于 2024-10-16 18:14:19 字数 90 浏览 6 评论 0原文

我想运行 JavaScript 代码来 ping 4 个不同的 IP 地址,然后检索这些 ping 请求的丢包和延迟并将其显示在页面上。

我该怎么做?

I want to run a JavaScript code to ping 4 different IP addresses and then retrieve the packet loss and latency of these ping requests and display them on the page.

How do I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

若能看破又如何 2024-10-23 18:14:19

你不能从 JS 做到这一点。您可以做的是:

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

向您的服务器发出 AJAX 请求,然后服务器将为您 ping 目标服务器,并在 AJAX 结果中返回结果。

可能的注意事项:

  • 这会告诉您是否可以从您的服务器(而不是用户的客户端)对目标服务器进行 ping 操作
    • 因此客户端将无法测试其 LAN 主机
    • 但您不应该让主机检查服务器内部网络上的主机(如果存在)
    • 某些主机可能会阻止来自某些主机的流量,但不会阻止其他主机的流量
  • 您需要的 其他主机的流量限制每台机器的 ping 计数:
    • 避免 AJAX 请求超时
    • 当您一直对某些网站运营商进行 ping 操作时,他们可能会感到非常沮丧
  • 资源 进行 ping 操作时,一些网站运营商可能会感到非常沮丧
    • 长时间运行的 HTTP 请求可能会达到服务器的最大连接限制,请检查它有多高
    • 许多用户同时尝试 ping 可能会产生可疑的流量(全部是 ICMP,仅此而已)
  • 并发 - 您可能希望池/缓存 up/down 状态至少几秒钟,以便多个希望 ping 同一目标的客户端不会发起大量 ping

You can't do this from JS. What you could do is this:

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

Make an AJAX request to your server, which will then ping the target servers for you, and return the result in the AJAX result.

Possible caveats:

  • this tells you whether the target servers are pingable from your server, not from the user's client
    • so the client won't be able to test hosts its LAN
    • but you shouldn't let the host check hosts on the server's internal network, if any exist
    • some hosts may block traffic from certain hosts and not others
  • you need to limit the ping count per machine:
    • to avoid the AJAX request from timing out
    • some site operators can get very upset when you keep pinging their sites all the time
  • resources
    • long-running HTTP requests could run into maximum connection limit of your server, check how high it is
    • many users trying to ping at once might generate suspicious-looking traffic (all ICMP and nothing else)
  • concurrency - you may wish to pool/cache the up/down status for a few seconds at least, so that multiple clients wishing to ping the same target won't launch a flood of pings
影子是时光的心 2024-10-23 18:14:19

我能想到的唯一方法是从外部服务器加载图像文件。当负载失败时,您“知道”服务器没有响应(您实际上不知道,因为服务器可能只是阻止您)。

看看这个示例代码就明白我的意思了:

 /*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 :(");
     }

}

The only method I can think of is loading e.g. an image file from the external server. When that load fails, you "know" the server isn't responding (you actually don't know, because the server could just be blocking you).

Take a look at this example code to see what I mean:

 /*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 :(");
     }

}
审判长 2024-10-23 18:14:19

我受到最新评论的启发,所以我写了这段快速代码。

这是一种“HTTP ping”,我认为与 XMLHttpRequest 调用()一起使用非常有用,例如找出在某些情况下使用最快的服务器或从用户的互联网收集一些粗略的统计数据连接速度。

这个小函数只是连接到一个不存在的 URL 上的 HTTP 服务器(预计返回 404),然后测量服务器响应 HTTP 请求的时间,并对累积时间求平均值和迭代次数。

所请求的 URL 在每次调用时都会随机修改,因为我注意到(可能)某些透明代理或缓存机制在某些情况下会伪造结果,从而给出额外的快速答案(实际上比 ICMP 更快,这有点奇怪)。

请注意使用适合真实 HTTP 服务器的 FQDN!
结果将显示到 id 为“result”的主体元素,例如:

<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"); 

请注意,我无法找到此脚本的结果数字与相应相同服务器上的 ICMP ping 之间的简单相关性,尽管 HTTP 响应时间似乎与 ICMP 响应时间大致成指数关系。这可以通过 HTTP 请求传输的数据量来解释,该数据量可能会根据 Web 服务器风格和配置、服务器本身的速度以及可能的其他原因而变化。

这不是很好的代码,但我认为它可以帮助并可能激励其他人。

I was inspired by the latest comment, so I wrote this quick piece of code.

This is a kind of "HTTP ping" which I think can be quite useful to use along with XMLHttpRequest calls(), for instance to figure out which is the fastest server to use in some case or to collect some rough statistics from the user's internet connexion speed.

This small function is just connecting to an HTTP server on an non-existing URL (that is expected to return a 404), then is measuring the time until the server is answering to the HTTP request, and is doing an average on the cumulated time and the number of iterations.

The requested URL is modified randomely at each call since I've noticed that (probably) some transparent proxies or caching mechanisms where faking results in some cases, giving extra fast answers (faster than ICMP actually which somewhat weird).

Beware to use FQDNs that fit a real HTTP server!
Results will display to a body element with id "result", for instance:

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

Function code:

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);
}

For instance, launch with:

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

Note that I couldn't find a simple corelation between result figures from this script and the ICMP ping on the corresponding same servers, though HTTP response time seems to be roughly-exponential from ICMP response time. This may be explained by the amount of data that is transfered through the HTTP request which can vary depending on the web server flavour and configuration, obviously the speed of the server itself and probably other reasons.

This is not very good code but I thought it could help and possibly inspire others.

杀手六號 2024-10-23 18:14:19

在 JS 中最接近 ping 的方法是使用 AJAX,并检索就绪状态、状态和标头。像这样:

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状态添加条件,并通过描述等使输出显示您想要的,以使其看起来更好。更像是一个 http url 状态检查器而不是 ping,但实际上是相同的想法。你总是可以循环它几次,让它感觉更像你的 ping :)

The closest you're going to get to a ping in JS is using AJAX, and retrieving the readystates, status, and headers. Something like this:

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();

Of course you can also put conditions in for different http statuses, and make the output display however you want with descriptions etc, to make it look nicer. More of an http url status checker than a ping, but same idea really. You can always loop it a few times to make it feel more like a ping for you too :)

夜声 2024-10-23 18:14:19

我想出了一些东西,因为我厌倦了几个小时又一个小时地寻找每个人都说“不可能”的东西,我唯一发现的就是使用 jQuery。
我想出了一种新的简单方法,使用 Vanilla JS(除了基本 JavaScript)。

这是我的 JSFiddle: https://jsfiddle.net/TheNolle/5qjpmrxg/74/

基本上,我创建一个名为“start”的变量,我给它时间戳,然后我尝试将不可见图像的源设置到我的网站(这不是图像)[可以更改为任何网站],因为它不是图像创建一个错误,我用它来执行代码的第二部分,此时我创建一个名为“end”的新变量,我从这里给出时间戳(与“start”不同)。然后,我简单地做一个减法(我从“结束”中减去“开始”),这给了我 ping 这个网站所需的延迟。
选择后,您可以将其存储在一个值中,将其粘贴到网页上,粘贴到控制台等。

let pingSpan = document.getElementById('pingSpan');
// Remove all the way to ...
let run;

function start() {
  run = true;
  pingTest();
}

function stop() {
  run = false;
  setTimeout(() => {
    pingSpan.innerHTML = "Stopped !";
  }, 500);
}

// ... here

function pingTest() {
  if (run == true) { //Remove line
    let pinger = document.getElementById('pingTester');
    let start = new Date().getTime();
    pinger.setAttribute('src', 'https://www.google.com/');
    pinger.onerror = () => {
      let end = new Date().getTime();
      // Change to whatever you want it to be, I've made it so it displays on the page directly, do whatever you want but keep the "end - start + 'ms'"
      pingSpan.innerHTML = end - start + "ms";
    }
    setTimeout(() => {
      pingTest();
    }, 1000);
  } // Remove this line too
}
body {
  background: #1A1A1A;
  color: white
}

img {
  display: none
}
Ping:
<el id="pingSpan">Waiting</el>
<img id="pingTester">

<br> <br>

<button onclick="start()">
  Start Ping Test
</button>
<button onclick="stop()">
  Stop
</button>

I've come up with something cause I was bored of searching hours after hours for something that everyone is saying "impossible", only thing I've found was using jQuery.
I've came up with a new simple way using Vanilla JS (nothing else than base JavaScript).

Here's my JSFiddle: https://jsfiddle.net/TheNolle/5qjpmrxg/74/

Basically, I create a variable called "start" which I give the timestamp, then I try to set an invisible image's source to my website (which isn't an image) [can be changed to any website], because it's not an image it creates an error, which I use to execute the second part of the code, at this time i create a new variable called "end" which i give the timestamp from here (which is different from "start"). Afterward, I simply make a substraction (i substract "start" from "end") which gives me the latency that it took to ping this website.
After you have the choice you can store that in a value, paste it on your webpage, paste it in the console, etc.

let pingSpan = document.getElementById('pingSpan');
// Remove all the way to ...
let run;

function start() {
  run = true;
  pingTest();
}

function stop() {
  run = false;
  setTimeout(() => {
    pingSpan.innerHTML = "Stopped !";
  }, 500);
}

// ... here

function pingTest() {
  if (run == true) { //Remove line
    let pinger = document.getElementById('pingTester');
    let start = new Date().getTime();
    pinger.setAttribute('src', 'https://www.google.com/');
    pinger.onerror = () => {
      let end = new Date().getTime();
      // Change to whatever you want it to be, I've made it so it displays on the page directly, do whatever you want but keep the "end - start + 'ms'"
      pingSpan.innerHTML = end - start + "ms";
    }
    setTimeout(() => {
      pingTest();
    }, 1000);
  } // Remove this line too
}
body {
  background: #1A1A1A;
  color: white
}

img {
  display: none
}
Ping:
<el id="pingSpan">Waiting</el>
<img id="pingTester">

<br> <br>

<button onclick="start()">
  Start Ping Test
</button>
<button onclick="stop()">
  Stop
</button>

夜夜流光相皎洁 2024-10-23 18:14:19
function ping(url){
 new Image().src=url
}

上面 ping 给定的 URL。

通常用于计数器/分析。

不会遇到客户端响应失败的情况(javascript)

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

Above pings the given Url.

Generally used for counters / analytics.

It won't encounter failed responses to client(javascript)

夜访吸血鬼 2024-10-23 18:14:19

我建议使用“head”仅请求标头。

xhr.open('head', 'asstes/imgPlain/pixel.txt' + cacheBuster(), true);

并请求就绪状态 2 - HEADERS_RECEIVED send() 已被调用,并且标头和状态可用。

xhr.onreadystatechange = function() {
    if (xhr.readyState === 2) { ...

I suggest using "head" to request the header only.

xhr.open('head', 'asstes/imgPlain/pixel.txt' + cacheBuster(), true);

and than ask for readystate 2 - HEADERS_RECEIVED send() has been called, and headers and status are available.

xhr.onreadystatechange = function() {
    if (xhr.readyState === 2) { ...
行至春深 2024-10-23 18:14:19

您无法使用 JavaScript 进行 PING。我创建了 Java servlet,如果还活着,则返回 10x10 像素的绿色图像;如果死了,则返回红色图像。 https://github.com/pla1/Misc/blob/master/README.md

You can't PING with Javascript. I created Java servlet that returns a 10x10 pixel green image if alive and a red image if dead. https://github.com/pla1/Misc/blob/master/README.md

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文