2011-02-10 19 views
7

Chcę uruchomić kod JavaScript, aby pingować 4 różne adresy IP, a następnie pobrać utratę pakietów i opóźnienia tych żądań ping i wyświetlić je na stronie.Jak pingować adresy IP za pomocą JavaScriptu

Jak to zrobić?

+0

Związane z [to pytanie] (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 Powinien sprawdzić powyższe rozwiązanie. Dość śliski. –

Odpowiedz

16

Nie można tego zrobić z JS. Co można zrobić, to w ten sposób:

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

Złóż wniosek AJAX do serwera, który będzie następnie ping serwery docelowe dla ciebie, i powrócić wynik w wyniku AJAX.

Ewentualne wyjątki:

  • to powie Ci, czy serwery docelowe są pingable z serwera, a nie od klienta użytkownika
    • więc klient nie będzie mógł przetestować hosty jej LAN
    • , ale nie powinieneś pozwolić hostowi na sprawdzenie hostów w wewnętrznej sieci serwera, jeśli istnieje, niektóre hosty mogą blokować ruch z niektórych hostów, a inne nie.
  • trzeba ograniczyć liczbę ping za maszyny:
    • , aby uniknąć żądania AJAX od momentu wyjścia
    • niektórzy operatorzy witryn mogą się bardzo zdenerwowany, gdy trzymasz pingowanie swoich stronach cały czas
  • zasoby
    • długotrwały żądań HTTP może uruchomić do maksymalnego limitu połączeń z serwerem, należy sprawdzić, jak wysoki jest
    • wielu użytkowników próbuje pingować naraz może wygenerować podejrzanie wyglądającego ruchu (wszystkie ICMP i nic innego)
  • współbieżności - może chcesz basenie/cache góra/dół stan przez kilka sekund, a przynajmniej tak że wielu klientów, którzy chcą pingować ten sam cel, nie uruchomi powodzi pingów
4

Jedyną metodą, którą mogę wymyślić jest ładowanie np. plik obrazu z zewnętrznego serwera. Kiedy to obciążenie się nie powiedzie, "wiesz", że serwer nie odpowiada (tak naprawdę nie wiesz, ponieważ serwer może po prostu blokować ciebie).

Spójrz na ten kod przykład aby zobaczyć, co mam na myśli:

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

To nie jest ping, to żądanie HTTP (a więc TCP/IP). Ponadto, jeśli cel nie uruchomi serwera HTTP, żądanie upłynie * czas oczekiwania * na przekroczenie limitu czasu; dodatkowo ładowanie jest asynchroniczne - chyba że obraz jest już w pamięci podręcznej, ImageObject.height zwróci 0, jeśli zaznaczysz go zaraz po ustawieniu 'src'; a jeśli * jest * w pamięci podręcznej, zwróci "Ping pracował", niezależnie od tego, czy cel się skończy, czy nie. http://en.wikipedia.org/wiki/Ping – Piskvor

+0

Relax Piskvor - masz całkowitą rację, że to nie jest PRAWDZIWA ping (nie jest to również twoje rozwiązanie) - musisz mieć możliwość otwierania gniazd i wysyłania dowolnych TCP/IP pakiety do symulacji ping - właśnie nazwałem metodę ping dla prostoty. Masz również rację, że jeśli cel nie uruchomi serwera HTTP, zajmie to dużo czasu - stąd napisałem "URL do znanego obrazu" ... Również buforowanie jest problemem. To była ** prosta ** demonstracja podejścia, które można zastosować, na tej samej zasadzie co ataki z historii CSS. Dzięki za upadek. –

+0

Nie odbierajcie tego osobiście, nie zezwalałem * ty *; Czułem, że tak naprawdę nie odpowiada na pytanie - chociaż * jest * prostym sposobem sprawdzenia, czy znany serwer HTTP może być w górze, to tak naprawdę nie odpowiada na utratę lub opóźnienie ping. Zgadzam się, że moje podejście nie polega na pingowaniu z komputera klienta, który wymagałby wielu obniżonych uprawnień i wielu luk bezpieczeństwa (i ActiveX). – Piskvor

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

Wyżej pingi Podany URL.
Generalnie używany do liczników/analiz.
Nie natknie się na nieudane odpowiedzi na klienta (javascript)

+0

to nie wyśle ​​pakietu ICMP – mulllhausen

+0

To sprawdzi, czy serwer odpowiada na żądanie, takie jak żądanie http. Ping to zupełnie inna sprawa. –

2

Najbliższe przejście do pingowania w JS polega na korzystaniu z AJAX, a także na pobieraniu danych o stanie gotowości, stanie i nagłówkach.Coś takiego:

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

Oczywiście można również umieścić warunki dla różnych stanów HTTP i sprawiają, że wyświetlacz wyjściowy jednak chcesz z opisami itp, aby wyglądać ładniej. Więcej sprawdzania statusu adresu URL niż ping, ale ten sam pomysł naprawdę. Zawsze możesz zapętlić go kilka razy, aby poczuć się bardziej jak ping dla ciebie :)

+0

Pomysł użycia AJAX i odzyskanie gotowych stanów działa dla mnie. Czy mogę zapytać, w jaki sposób mogę dodać statystykę else w tej treści. Na przykład, jeśli adres URL nie jest dostępny, chciałbym wydrukować masaż użytkownikowi. Podobnie jak document.getElementById ("div"). InnerHTML = "Ping nie jest sukcesem!"; –

2

Zainspirował mnie najnowszy komentarz, więc napisałem ten szybki kawałek kodu.

Jest to rodzaj "pingowania HTTP", który, jak sądzę, może być całkiem użyteczny w połączeniu z wywołania XMLHttpRequest(), na przykład w celu ustalenia, który jest najszybszym serwerem do użycia w niektórych przypadkach lub w celu zebrania pewnych statystyk od prędkości połączenia internetowego użytkownika.

Ta niewielka funkcja polega na łączeniu się z serwerem HTTP za pomocą nieistniejącego adresu URL (który ma zwrócić 404), a następnie mierzy czas do momentu, w którym serwer odpowiada na żądanie HTTP i wykonuje średnią w skumulowanym czasie i liczbie iteracji.

Żądany adres URL jest modyfikowany losowo przy każdym połączeniu, ponieważ zauważyłem (prawdopodobnie) niektóre transparentne proxy lub mechanizmy buforowania, w których fałszowanie wyników w niektórych przypadkach daje dodatkowe szybkie odpowiedzi (szybciej niż ICMP, co w pewnym sensie dziwne).

Pamiętaj, aby używać nazw FQDN, które pasują do prawdziwego serwera HTTP! Wyniki będą wyświetlane na elemencie ciała z id "Wynik", na przykład: Kod

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

Function:

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

na przykład uruchomienie z:

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

pamiętać, że nie udało się znaleźć prostej korelacji między wynikami wyników z tego skryptu i pingiem ICMP na odpowiednich samych serwerach, chociaż czas reakcji HTTP wydaje się być w przybliżeniu wykładniczy od czasu ICMP czas sponse. Można to wyjaśnić ilością danych przesyłanych za pośrednictwem żądania HTTP, które mogą się różnić w zależności od smaku i konfiguracji serwera WWW, oczywiście od szybkości samego serwera i prawdopodobnie z innych powodów.

To niezbyt dobry kod, ale pomyślałem, że może pomóc i zainspirować innych.

-1

Is it possible to ping a server from Javascript?

powinien sprawdzić powyższe rozwiązanie. Dość śliski.

Nie moje, oczywiście, ale chciałem to wyjaśnić.

+0

W przypadku głosowania w dół ta odpowiedź nie ma sensu. Pytanie brzmiało, jak pingować przy użyciu Javascript, a link pokazuje, jak skutecznie pingować przy użyciu Javascript. Nie jestem pewien, czego jeszcze można się spodziewać. Dziękuję za odjęcie rep, bardzo doceniane. Łał. –

Powiązane problemy