2011-02-10 77 views
7

Tôi muốn chạy mã JavaScript để ping 4 địa chỉ IP khác nhau và sau đó truy xuất mất gói và độ trễ của các yêu cầu ping này và hiển thị chúng trên trang.Cách ping địa chỉ IP bằng cách sử dụng JavaScript

Làm cách nào để thực hiện việc này?

+0

Liên quan đến [câu hỏi này] (http://stackoverflow.com/questions/4954587/getting-client-to-automatically-send-data-to-server). –

+0

http://stackoverflow.com/questions/4282151/is-it-possible-to-ping-a-server-from-javascript Nên kiểm tra giải pháp trên. Khá trơn. –

Trả lời

16

Bạn không thể thực hiện việc này từ JS. Những gì bạn có thể làm là:

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

Thực hiện yêu cầu AJAX cho máy chủ, sau đó ping máy chủ đích cho bạn và trả về kết quả trong kết quả AJAX.

hãy cẩn thận có thể xảy ra:

  • này cho bạn biết các máy chủ mục tiêu là có thể ping được từ máy chủ của bạn, chứ không phải từ khách hàng của người dùng
    • vì vậy khách hàng sẽ không thể để kiểm tra host LAN của nó
    • nhưng bạn không nên để máy chủ lưu trữ kiểm tra trên mạng nội bộ của máy chủ, nếu có tồn tại
    • một số máy chủ có thể chặn lưu lượng truy cập từ một số máy chủ nhất định chứ không phải người khác
  • bạn cần phải hạn chế số lượng ping cho mỗi máy:
    • để tránh yêu cầu AJAX từ thời điểm ra
    • một số nhà khai thác trang web có thể nhận được rất khó chịu khi bạn giữ ping trang web của họ mọi lúc
  • nguồn
    • dài chạy các yêu cầu HTTP có thể chạy vào giới hạn kết nối tối đa của máy chủ của bạn, kiểm tra cao bao nhiêu nó là
    • nhiều người sử dụng cố gắng ping cùng một lúc có thể tạo ra lưu lượng đáng ngờ nhìn (tất cả ICMP và không có gì khác)
  • đồng thời - bạn có thể muốn hồ bơi/bộ nhớ cache lên/xuống trạng thái cho một vài giây ít nhất, vì vậy nhiều khách hàng có nhu cầu ping cùng một mục tiêu sẽ không khởi chạy một lũ pings
4

Phương pháp duy nhất tôi có thể nghĩ là đang tải ví dụ một tệp hình ảnh từ máy chủ bên ngoài. Khi tải không thành công, bạn "biết" máy chủ không phản hồi (bạn thực sự không biết, vì máy chủ có thể chặn bạn).

Hãy nhìn vào mã ví dụ này để xem những gì tôi có nghĩa là:

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

Đó không phải là ping, đó là một yêu cầu HTTP (do đó TCP/IP). Ngoài ra, nếu mục tiêu không chạy máy chủ HTTP, yêu cầu sẽ mất thời gian * loooong * để hết thời gian chờ; Ngoài ra, tải là không đồng bộ - trừ khi hình ảnh đã có trong bộ nhớ cache, ImageObject.chiều cao sẽ trả về 0 nếu bạn kiểm tra nó ngay sau khi thiết lập 'src'; và nếu nó * là * trong bộ nhớ cache, nó sẽ trả về "Ping làm việc", cho dù mục tiêu là lên hay không. http://en.wikipedia.org/wiki/Ping – Piskvor

+0

Relax Piskvor - bạn hoàn toàn chính xác rằng đây không phải là một ping REAL (không phải là giải pháp của bạn) - bạn sẽ cần để có thể mở ổ cắm và gửi TCP/IP tùy ý các gói tin để mô phỏng một ping - Tôi vừa gọi phương thức ping để đơn giản. Bạn cũng chính xác rằng nếu mục tiêu không chạy một máy chủ HTTP, nó sẽ mất một thời gian dài - do đó tôi đã viết "URL cho một hình ảnh được biết đến" ... Ngoài ra bộ nhớ đệm là một vấn đề. Đây là một cuộc biểu tình ** đơn giản ** về cách tiếp cận mà bạn có thể thực hiện, cùng nguyên tắc như là hack lịch sử CSS. Cảm ơn cho downvote. –

+0

Đừng lấy cá nhân downvote, tôi không downvote * bạn *; Tôi chỉ cảm thấy rằng nó không thực sự trả lời câu hỏi - mặc dù nó * là * một cách đơn giản để kiểm tra xem một máy chủ HTTP đã biết có đang hoạt động hay không, nó không thực sự trả lời sự mất mát hoặc độ trễ ping. Tôi đồng ý rằng cách tiếp cận của tôi không ping từ máy tính của khách hàng, điều đó đòi hỏi rất nhiều quyền hạn và nhiều lỗ hổng bảo mật (và ActiveX). – Piskvor

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

ping Phía trên Url nhất định.
Thường được sử dụng cho bộ đếm/phân tích.
Nó sẽ không gặp phải phản hồi không thành công cho khách hàng (javascript)

+0

điều này sẽ không gửi gói icmp – mulllhausen

+0

Điều này sẽ kiểm tra xem máy chủ có phản hồi yêu cầu hay không, chẳng hạn như yêu cầu http. Một ping là một điều hoàn toàn khác. –

2

Gần nhất bạn sẽ nhận được ping trong JS đang sử dụng AJAX và truy xuất các trạng thái, trạng thái và tiêu đề.Một cái gì đó như thế này:

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

Tất nhiên, bạn cũng có thể đặt điều kiện cho các trạng thái http khác nhau và hiển thị đầu ra theo ý muốn, vv để trông đẹp hơn. Nhiều người kiểm tra trạng thái url http hơn là ping, nhưng thực sự là ý tưởng tương tự. Bạn luôn có thể lặp lại nó vài lần để làm cho nó cảm thấy giống như một ping cho bạn quá :)

+0

Ide của việc sử dụng AJAX và lấy các trạng thái sẵn sàng là công trình cho tôi. Tôi có thể hỏi làm thế nào tôi có thể thêm một statemen khác trong nội dung này. Giống như nếu url không có sẵn tôi muốn in một massage cho người dùng. Giống như document.getElementById ("div"). InnerHTML = "Ping không thành công!"; –

2

Tôi lấy cảm hứng từ nhận xét mới nhất, vì vậy tôi đã viết đoạn mã nhanh này.

Đây là loại "ping HTTP" mà tôi nghĩ có thể khá hữu ích khi sử dụng cùng với các cuộc gọi XMLHttpRequest(), ví dụ để tìm ra máy chủ nhanh nhất để sử dụng trong một số trường hợp hoặc thu thập một số thống kê thô từ tốc độ kết nối internet của người dùng.

Chức năng nhỏ này chỉ kết nối với máy chủ HTTP trên URL không tồn tại (dự kiến ​​trả lại 404), sau đó đo thời gian cho đến khi máy chủ trả lời yêu cầu HTTP và đang thực hiện trung bình vào thời gian tích lũy và số lần lặp lại.

URL được yêu cầu được sửa đổi ngẫu nhiên tại mỗi cuộc gọi vì tôi nhận thấy (có thể) một số proxy trong suốt hoặc cơ chế lưu vào bộ nhớ đệm, trong đó có kết quả giả mạo trong một số trường hợp, trả lời nhanh hơn (nhanh hơn ICMP).

Cẩn thận khi sử dụng FQDN phù hợp với máy chủ HTTP thực! Kết quả sẽ hiển thị cho một yếu tố cơ thể với id "kết quả", ví dụ: Mã

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

Chức năng:

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

Ví dụ, ra mắt với:

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

Lưu ý rằng tôi không thể tìm thấy một corelation đơn giản giữa các con số kết quả từ kịch bản này và ICMP ping trên các máy chủ tương ứng tương tự, mặc dù thời gian phản hồi HTTP có vẻ là gần đúng theo hàm mũ từ ICMP thời gian phản ứng. Điều này có thể được giải thích bởi lượng dữ liệu được chuyển qua yêu cầu HTTP có thể thay đổi tùy thuộc vào hương vị và cấu hình máy chủ web, rõ ràng là tốc độ của máy chủ và có thể là các lý do khác.

Đây không phải là mã rất tốt nhưng tôi nghĩ rằng nó có thể giúp và có thể truyền cảm hứng cho người khác.

-1

Is it possible to ping a server from Javascript?

nên kiểm tra giải pháp trên. Khá trơn.

Không phải của tôi, rõ ràng, nhưng muốn làm rõ điều đó.

+0

Xuống bỏ phiếu cho câu trả lời này không có ý nghĩa. Câu hỏi đặt ra là cách ping bằng cách sử dụng Javascript và liên kết cho bạn thấy cách ping hiệu quả bằng cách sử dụng Javascript. Không chắc người khác có thể mong đợi điều gì. Cảm ơn cho trừ trừ, mặc dù nhiều đánh giá cao. Wow. –

Các vấn đề liên quan