2011-02-10 292 views
7

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

我该怎么做?

+0

与[此问题]相关(http://stackoverflow.com/questions/4954587/getting-client-to-automatically-send-data-to-server)。 – 2011-02-10 08:18:11

+0

http://stackoverflow.com/questions/4282151/is-it-possible-to-ping-a-server-from-javascript应该检查出上述解决方案。很漂亮。 – 2017-04-16 21:50:32

回答

16

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

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

做一个AJAX请求到服务器,然后将ping目标服务器为你,在AJAX结果返回结果。

可能的警告:

  • 这告诉你目标服务器是否从你的服务器ping命令,而不是从用户的客户端
    • ,所以客户端将无法测试主机的LAN
    • 但你不应该让服务器的内部网络上的主机检查主机上,如果存在任何
    • 某些主机可能会阻止某些主机的流量,而不是别人
  • 需要限制每台机器的平计数:
    • 避免超时AJAX请求
    • 当你继续ping自己的网站所有的时间一些网站运营商可以很心烦
  • 资源
    • 长期运行的HTTP请求可能会遇到你的服务器的最大连接数限制,检查它有多高
    • 许多用户尝试ping一次可能产生可疑的流量(所有ICMP,并没有别的)
  • 并发 - 你不妨池/缓存启动/关闭状态至少几秒钟,所以多个客户希望ping相同的目标不会启动ping的大量
4

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

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

/*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

这不是ping,那是一个HTTP请求(因此是TCP/IP)。另外,如果目标不运行HTTP服务器,请求将花费一段时间超时;另外,加载是异步的 - 除非图像已经在缓存ImageObject中。如果在设置`src`后检查它,高度将返回0;如果它*在高速缓存中,它将返回“Ping工作”,无论目标是否启动。 http://en.wikipedia.org/wiki/Ping – Piskvor 2011-02-10 08:34:20

+0

放松Piskvor - 你是完全正确的,这不是一个真正的ping(你的解决方案也不是) - 你需要能够打开套接字并发送任意TCP/IP数据包模拟一个ping - 我只是简单地称为ping方法。你也是正确的,如果目标没有运行HTTP服务器,它将需要很长时间 - 因此我写了“URL到一个已知的图像”......同时缓存是一个问题。这是一个**简单的**示范,您可以采用的方法,与CSS历史记录相同的原则。感谢downvote。 – 2011-02-10 10:26:50

+0

不要个人采取downvote,我没有downvote *你*;我只是觉得它没有真正回答这个问题 - 尽管它*是检查一个已知的HTTP服务器是否可以启动的简单方法,但它并不真正回答ping损失或等待时间。我同意我的方法不是从客户端的计算机上执行ping命令,这需要大量的权限下降以及许多安全漏洞(和ActiveX)。 – Piskvor 2011-02-10 11:11:02

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

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

2

最接近你在JS中使用的平台是使用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状态,并进行输出显示,但是你想使用说明等,使它看起来更好。更多的是一个http url状态检查器,而不是一个ping,但真的是一样的想法。你总是可以循环几次,让它感觉更像是一个ping你:)

2

我的灵感来自最新的评论,所以我写了这段快速的代码。

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

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

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

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

<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服务器的风格和配置,显然是服务器本身的速度以及可能的其他原因。

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