【问题标题】:How to ping IP addresses using JavaScript如何使用 JavaScript ping IP 地址
【发布时间】:2011-06-24 16:39:47
【问题描述】:

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

我该怎么做?

【问题讨论】:

标签: javascript ping latency


【解决方案1】:

你不能从 JS 做到这一点。你可以这样做:

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

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

可能的警告:

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

【讨论】:

    【解决方案2】:

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

    看看这个示例代码,看看我的意思:

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

    【讨论】:

    • 这不是 ping,这是一个 HTTP 请求(因此是 TCP/IP)。此外,如果目标没有运行 HTTP 服务器,则请求将需要 loooong 时间才能超时;另外,加载是异步的——除非图像已经在缓存中,如果你在设置src 后立即检查它,ImageObject.height 将返回 0;如果它 is 在缓存中,无论目标是否启动,它都会返回“Ping working”。 en.wikipedia.org/wiki/Ping
    • 放松 Piskvor - 你完全正确,这不是真正的 ping(你的解决方案也不是) - 你需要能够打开套接字并发送任意 TCP/IP 数据包来模拟 ping -为了简单起见,我只是调用了 ping 方法。你也是正确的,如果目标不运行 HTTP 服务器,它将需要很长时间 - 因此我写了“URL to a known image”......缓存也是一个问题。这是您可以采用的方法的简单演示,原理与 CSS 历史黑客相同。感谢您的反对。
    • 不要亲自投票,我没有投票;我只是觉得它并没有真正回答问题——尽管它一种检查已知 HTTP 服务器是否启动的简单方法,但它并没有真正回答 ping 丢失或延迟问题。我同意我的方法不是从客户端的计算机 ping,这将需要大量降低的权限和许多安全漏洞(和 ActiveX)。
    • 不接受个人 :-) 感谢您的跟进
    • 警告: 以上将缓存。请务必在 URL 的末尾附加一些独特的内容。此外,一个单独的 IP/域同样适用于图像 src:"http://" + ipOrHost + "?pingedat=" + new Date().getTime();
    【解决方案3】:

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

    这是一种“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"); 
    

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

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

    【讨论】:

      【解决方案4】:

      在 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 :)

      【讨论】:

      • 使用 AJAX 并检索就绪状态的想法对我有用。请问如何在此内容中添加其他声明者。就像如果 url 不可用,我想给用户打印一条消息。比如 document.getElementById("div").innerHTML = "Ping 不成功!";
      【解决方案5】:

      我想出了一些东西,因为我厌倦了数小时后搜索每个人都说“不可能”的东西,我发现的唯一东西就是使用 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>

      【讨论】:

        【解决方案6】:
        function ping(url){
         new Image().src=url
        }
        

        以上 ping 给定的 Url。
        通常用于计数器/分析。
        不会遇到客户端响应失败(javascript)

        【讨论】:

        • 这不会发送icmp数据包
        • 这将检查服务器是否响应请求,例如 http 请求。 ping 是完全不同的事情。
        【解决方案7】:

        Is it possible to ping a server from Javascript?

        应该看看上面的解决方案。很漂亮。

        显然不是我的,但我想澄清一下。

        【讨论】:

        • 否决这个答案没有意义。问题是如何使用 Javascript 进行 ping,该链接向您展示了如何使用 Javascript 有效地 ping。不知道还有什么人可以期待。感谢您的代表减法,非常感谢。哇。
        【解决方案8】:

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

        【讨论】:

          猜你喜欢
          • 2013-09-08
          • 2012-07-15
          • 2018-01-14
          • 1970-01-01
          • 1970-01-01
          • 2013-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多