2012-01-20 15 views
5

Jest to ostatecznie rozwiązane z atrybutem "timeout" jQuery AJAX (i JSONP). Zobacz moją własną odpowiedź!Jak sprawdzić, czy port jest otwarty w sieci klienta/zaporze?

Proszę zobaczyć zaktualizowaną część, próbowałem też z apletem. I nie zawaha się przyjąć twojej odpowiedzi, jeśli możesz podać rozwiązanie z implementacją apletu.

Pracuję z aplikacją WWW opartą na języku Java. Moim żądaniem jest sprawdzenie, czy dany port (powiedzmy 1935) jest otwarty lub zablokowany po stronie klienta. Zaimplementowałem "jsonp" (dlaczego "jsonp"? Stwierdziłem, że żądanie "http" za pośrednictwem AJAX nie może działać dla corssdomain dla samej zasady pochodzenia przeglądarki ") AJAX wywołanie na jeden z mojego serwera zawierającego konkretny port. A jeśli serwer zwróci xhr.status == 200, port jest otwarty. Oto wada, której nie mogę wykonać oczekiwania na wykonanie (synchroniczne), dopóki nie zakończy się połączenie. Oto funkcja JavaScript, której używam.

Jakiekolwiek alternatywne rozwiązanie (musi być rzeczą po stronie klienta musi być równoległa do mojej aplikacji, proszę nie sugeruj python/php/innych języków) jest również mile widziane. Dziękujemy za poświęcony czas.

function checkURL() { 

    var url = "http://10.0.5.255:1935/contextname" ; 
    var isAccessible = false; 

    $.ajax({ 
     url: url, 
     type: "get", 
     cache: false, 
     dataType: 'jsonp', 
     crossDomain : true, 
     asynchronous : false, 
     jsonpCallback: 'deadCode', 
     complete : function(xhr, responseText, thrownError) { 
      if(xhr.status == "200") { 
       isAccessible = true; 
       alert("Request complete, isAccessible==> " + isAccessible); // this alert does not come when port is blocked 
      } 
     } 
    }); 

    alert("returning isAccessible=> "+ isAccessible); //this alert comes 2 times before and after the AJAX call when port is open 
    return isAccessible; 

} 

function deadCode() { 
    alert("Inside Deadcode"); // this does not execute in any cases 
} 

------------------------------------------ ---------------AKTUALIZACJA---------------------------------- ------------------------------

Próbowałem z apletem Java (dzięki sugestii Y Martina). To działa dobrze w appletviewer. Ale kiedy dodaję aplet na stronie HTML, daje to wrażliwe wyniki. Podatne w tym sensie, kiedy zmieniam kartę lub zmieniam rozmiar przeglądarki, wartość portAvailable zmienia się w drukowanej wiadomości.

Kod Applet:

import java.applet.Applet; 
import java.awt.Graphics; 
import java.net.InetSocketAddress; 
import java.net.Socket; 

public class ConnectionTestApplet extends Applet { 
    private static boolean portAvailable; 
    public void start() { 
     int delay = 1000; // 1 s 
     try { 
      Socket socket = new Socket(); 
       /*****This is my tomcat5.5 which running on port 1935*************/ 
       /***I can view it with url--> http://101.220.25.76:1935/**********/ 
      socket.connect(new InetSocketAddress("101.220.25.76", 1935), delay); 
      portAvailable = socket.isConnected(); 
      socket.close(); 
      System.out.println("init() giving---> " + portAvailable); 
     } 
     catch (Exception e) { 
      portAvailable = false; 
      System.out.println("init() giving---> " + portAvailable); 
      System.out.println("Threw error---> " + e.getMessage()); 
     } 

    } 
    public void paint(Graphics g) { 
     System.out.println("Connection possible---> " + portAvailable); 
     String msg = "Connection possible---> " + portAvailable; 
     g.drawString(msg, 10, 30); 
    } 
} 

A to jest moja strona HTML (jestem gospodarzem go na tym samym komputerze z innym Tomcat 6, która działa na porcie 9090. Mogę zobaczyć tą stronę z url --->http://101.220.25.76:9090/test/):

<html> 
<body> 
     <applet code="ConnectionTestApplet" width=300 height=50> 
     </applet> 
</body> 
</html> 

A jak robie z portu 1935 blokowania i openning?

Utworzono regułę zapory zarówno dla ruchu przychodzącego, jak i wychodzącego dla portu 1935. Sprawdzam otwarty/zablokowany scenariusz portu 1935, wyłączając/włączając obie reguły.

To jest moja S.S.C.C.E. Teraz pomóżcie mi :)

+1

Twój kod sprawdza nie tylko, czy "port" jest otwarty, ale także czy serwer odpowiada na żądanie HTTP. Czy Twój kod musi działać w przeglądarce? Może być apletem Javy rozwiązaniem dla Ciebie? –

+0

Aplet jest opcją, która zależy od dostępności wtyczki java przeglądarki, której chcę uniknąć. Mam ustawiony serwer, który odpowiada na porcie 1935, niezależnie od tego, jaki będzie protokół (tak, to jest HTTP). Otrzymuję również odpowiedź (gdy port jest otwarty). Ale jeśli port jest blokowany po stronie klientów, jak mam tego słuchać? to jest punkt – tusar

+0

@ YvesMartin, czy mógłbyś napisać odpowiedź na temat apletu lub jakiejkolwiek innej implementacji? Tak, chcę, aby kod był wykonywany w przeglądarce. Pomóż mi z tym. – tusar

Odpowiedz

4

Gotcha !!! Rozwiązałem mój problem z wywołaniem JSONP i jQuery AJAX.Odkryłem atrybutjQuery AJAX i mój kod został wykonany płynnie, gdy port został zablokowany lub otwarty. Oto rozwiązanie dla przyszłych użytkowników. Dziękuję wszystkim odbierającym za wkład.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
     <script type="text/javascript" src="jquery-1.7.2-min.js"></script> 
    </head> 
    <body> 
     <script type"text/javascript"> 
      var isAccessible = null; 
      function checkConnection() { 
       var url = "http://101.212.33.60:1935/test/hello.html" ; 
       $.ajax({ 
        url: url, 
        type: "get", 
        cache: false, 
        dataType: 'jsonp', // it is for supporting crossdomain 
        crossDomain : true, 
        asynchronous : false, 
        jsonpCallback: 'deadCode', 
        timeout : 1500, // set a timeout in milliseconds 
        complete : function(xhr, responseText, thrownError) { 
         if(xhr.status == "200") { 
          isAccessible = true; 
          success(); // yes response came, esecute success() 
         } 
         else { 
          isAccessible = false; 
          failure(); // this will be executed after the request gets timed out due to blockage of ports/connections/IPs 
         } 
        } 
       }); 
      } 
      $(document).ready(function() { 
       checkConnection(); // here I invoke the checking function 
      }); 
     </script> 
    </body> 
</html> 
+0

Świetnie! Jestem prawie pewien, że ta opcja "timeout" jest realizowana dzięki JS "setTimeout" –

+0

dziękuję za wskazanie i cieszę się, że wszyscy widzą to jako "najlepszą odpowiedź", co jest poprawne, do tego stopnia, że ​​nie wymaga wyjaśnień. żadnych ukrytych informacji, takich jak inne odpowiedzi, pół umysłów, połowa komentarzy ... co za bałagan! Nie zapomnę o tak haniebnej sytuacji na SO. – tusar

+0

Zgadzam się z Tobą. Powinienem spojrzeć na mój pomysł "timeout", który znam z doświadczenia JavaScript i Java na interfejs API jQuery, zamiast podążać ścieżką innych odpowiedzi ... Mam nadzieję, że się o tym dowiedziałem. –

2

Nie sądzę, że rozumiesz przypadki użycia JSONP i nie można przetestować z nimi otwartych portów. http://en.wikipedia.org/wiki/JSONP

Jeśli potrzebujesz rozwiązania po stronie klienta, możliwe jest korzystanie z gniazd internetowych, ale jest to dostępne tylko w nowych przeglądarkach, takich jak chrome lub ff. W przeciwnym razie zażądaj skryptu po stronie serwera, który wykonuje polecenie ping. Na przykład - ze skryptem curl: curl and ping - how to check whether a website is either up or down?

+0

Zapomniałem oznaczyć to java. Nie mogę użyć 'curl'. to jest PHP? wybacz mi, jeśli się mylę. Jakieś inne rozwiązania? – tusar

+0

W Javie możesz znacznie poprawić połączenia sieciowe z klasą URL lub Socket: http://stackoverflow.com/questions/3584210/preferred-java-way-to-ping-a-http-url-for-availability –

+0

Ya , rozumiesz.zobacz kod Java zostanie wykonany na serwerze. dobrze? gdzie zawsze będę otwierać port. Ale jest to problem z klientem, w którego sieci port może być zablokowany. W takich przypadkach nie mogę uruchamiać niczego oprócz JavaScript. – tusar

1

Nie można tego zrobić w JavaScript, ponieważ nie ma on obsługi prawdziwego gniazda, a JavaScript można testować tylko na obecność gniazda HTTP. Możesz użyć Javy (JavaScript nie jest Javą) i napisać odpowiedni aplet Javy, aby to zrobić.

Należy również przeczytać Q&A How to Ping in java

Spróbuj użyć isReachable

+0

przede wszystkim dziękuję za poświęcony czas. Nikt nie patrzy na to wcale ... tak smutno. chciałbyś dać mi przykład z apletem. Próbowałem go zaprojektować, ale spowodowało bałagan. Czy możesz podać mi przykład/referencje? – tusar

+0

Jedna aktualizacja, mój applet podaje poprawny wynik (o dostępności portu) w aplet-viewer, ale w przeglądarce jego wyniki buforowania chyba. jakieś sugestie ? – tusar

+0

Witam, zaktualizowałem pytanie z wynikami, czy mógłbyś rzucić okiem? – tusar

0

W JavaScript, trzeba pracować wokół asynchronicznego kwestii. Oto propozycja:

  • Strona HTML wyświetla animowany obraz jako pasek postępu
  • wywołaniu checkURL
  • Po zarówno otrzymaniu telefonicznego lub określony limit czasu, po zmianie wyświetlacz dla komunikatu o błędzie lub czynić się do pracy, aby zrobić

podstawie following document z wykorzystaniem XMLHttpRequest, oto przykładowy kod dla checkURL:

var myrequest = new ajaxRequest(); 
var isAccessible = false; 
myrequest._timeout = setTimeout(function() { 
     myrequest.abort(); 
     displayErrorMessage(); 
    }, 
    1000 
    ) //end setTimeout 
myrequest.onreadystatechange = function() { 
    if (myrequest.readyState == 4) { //if request has completed 
     if (myrequest.status == 200) { 
     isAccessible = false; 
     goOnWithTheJob(); 
     } else { 
     displayErrorMessage(); 
     } 
    } 
myrequest.open("GET", url, true); 
myrequest.send(null); //send GET request 
// do nothing - wait for either timeout or readystate callback 

Ten kod pozwala 1 sekundę na uzyskanie odpowiedzi 200 z protokołu HTTP GET dla zasobu podstawowego.

W lokalnym teście otrzymujesz natychmiastową odpowiedź, ponieważ system odpowiada zerowanie połączenia, jeśli port jest zamknięty, ale firewall po prostu nie odpowiada.

Nawet jeśli metoda open mogą być używane synchronicznie, polecam korzystanie z zegarem, ponieważ kod jest prawdopodobnie czekać na TCP timeout i ponownych prób (3 x 1 minuta?) Jako zapora zwykle po prostu odrzuca pakiety na zamknięte porty i może odrzucić pakiety ICMP, uniemożliwiając przetestowanie dostępności za pomocą ping. I wyobrażam sobie, że oczekiwanie na tak długie czekanie nie jest oczekiwane.

+0

Myślę, że timeout może nie być dobrym pomysłem. Spróbuję tego z JSON-P (tak jak to określiłem, potrzebuję domeny międzydomenowej). Wkrótce się odezwę. dziękuję za Twój czas. – tusar

+0

Dlaczego "nie jest to dobry pomysł"? Jest wystarczająco daleko, aby sprawdzić dostępność serwera/portu. Użyłem takiego kodu dla złożonego klienta html/javascript, aby obsługiwać tryb online/offline z regularnymi próbami połączeń i paskiem postępu dla użytkownika ... Więc proszę rozważ to i przetestuj –

1

Zamiast apletu można użyć komponentu flash. Za pomocą klasy Socket dostępnej w ActionCcript można otworzyć połączenie TCP z pamięci flash do portu na serwerze, aby sprawdzić, czy jest otwarte. Jednak w oparciu o wersję Flash Playera plik polityki musi zostać umieszczony na serwerze, na którym jest otwarte gniazdo.

+0

hi Ali, nie robię plików flash. Czy możesz dzielić się, jeśli go masz? Myślę, że powinny to być najlepsze sposoby na zrobienie tego. – tusar

+0

cześć, zaktualizowałem pytanie z wynikami, czy mógłbyś rzucić okiem? – tusar

2

Oto kod Java jako aplet aby przetestować łączność serwer/port:

import java.io.*; 
import java.net.*; 

public class ConnectionTestApplet extends Applet { 
    public void start() { 
     boolean portAvailable = false; 
     int delay = 1000; // 1 s 
     try { 
      Socket socket = new Socket(); 
      socket.connect(new InetSocketAddress("server.domain.com", 1935), delay); 
      portAvailable = socket.isConnected(); 
      socket.close(); 
     } catch (UnknownHostException uhe) { 
      uhe.printStackTrace(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
     System.out.println("Connection possible: " + portAvailable); 
    } 
} 

Trzeba jeszcze uzyskać informacje z apletu zrobić coś innego z tego wyniku. Najprostszym sposobem jest przekierowanie przeglądarki do getAppletContext().showDocument(url) dzięki

+0

Witam Martin, próbowałem tego i zaktualizowałem pytanie z wynikami, czy mógłbyś rzucić okiem? – tusar

1

to sprawdzić:

http://blog.andlabs.org/2010/12/port-scanning-with-html5-and-js-recon.html

z JS-Recon, można wykonać skanowanie portów z javascript. Możesz po prostu wskazać lokalny adres IP. Sądzę, że działa to poprzez podłączenie gniazd internetowych/cors do dowolnego gniazda ip/socket i mierzenie timeoutów. To nie jest doskonałe podejście, ale ostatecznie może to być granica javascript.

Jeśli możesz to zrobić w aplikacji aplet/flash java, może to być lepsze, ponieważ mają dostęp na niższym poziomie.

+0

Przysięgam, że wcześniej o tym nie słyszałem. I dzięki za dobre pomysły w ostatnim paragrafie. Na pewno popatrzę na te API. Dziękuję Ci bardzo. A jeśli jesteś zainteresowany, aby zobaczyć, jak rozwiązałem mój problem, zobacz moją własną odpowiedź! – tusar

Powiązane problemy