2012-01-20 4 views
5

Это, наконец, решение с атрибутом «timeout» jQuery AJAX (и JSONP). Смотрите мой собственный ответ!Как проверить, открыт ли порт в сети клиента/брандмауэре?

Пожалуйста, ознакомьтесь с обновленной частью, я также попробовал апплет. И не стесняйтесь принять ваш ответ, если вы сможете дать решение с реализацией апплета.

Я работаю с веб-приложением на основе Java. Мое требование - проверить, открыт или заблокирован конкретный порт (например, 1935) на стороне клиента. Я реализовал «jsonp» (почему «jsonp»? Я обнаружил, что запрос «http» через AJAX не может работать для corssdomain для той же политики происхождения браузеров). AJAX-вызов на один из моих серверов, содержащих определенный порт. И если сервер возвращает xhr.status == 200, то порт открыт. Вот недостаток, который я не могу заставить ждать выполнения (синхронно) до завершения вызова. Вот функция JavaScript, которую я использую.

Любое альтернативное решение (должно быть на стороне клиента должно быть параллельно с моим приложением, пожалуйста, не предлагайте python/php/другие языки) также приветствуется. Спасибо за ваше время.

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 
} 

------------------------------------------ ---------------ОБНОВИТЬ---------------------------------- ------------------------------

Я пробовал использовать Java-апплет (благодаря предложению Y Мартина). Это отлично работает в appletviewer. Но когда я добавляю апплет в HTML-страницу, он дает уязвимые результаты. Уязвимым в смысле, когда я изменяю вкладку или изменяю размер браузера, значение portAvailable изменяется в напечатанном сообщении.

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

И это мой HTML страницы (я разместить его на одном компьютере с другой Tomcat 6, который работает на порту 9090. Я могу просматривать эту страницу с URL --->http://101.220.25.76:9090/test/):

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

и как я делаю порт 1935 блокирования и открывающиеся?

Я создал правило брандмауэра как для входящего, так и исходящего для порта 1935. Я проверяю сценарий открытия/блокировки порта 1935, отключив/разрешив оба правила.

Это мой S.S.C.C.E. Теперь, пожалуйста, помогите мне :)

+1

Ваш код не только проверяет, открыт ли «порт», но также есть сервер, отвечающий на HTTP-запрос. Нужен ли ваш код для запуска в браузере? Может быть, апплет Java для вас? –

+0

Апплет - это вариант, который зависит от доступности java-плагина браузера, которого я хочу избежать. Я настроил сервер, который отвечает на порт 1935 независимо от протокола (да, это HTTP). Я также получаю ответ (когда порт открыт). Но если порт заблокирован на конце клиента, как я его слушаю? это точка – tusar

+0

@YvesMartin, не могли бы вы разместить сообщение об апплете или любой другой реализации? Да, я хочу, чтобы код выполнялся в браузере. Пожалуйста, помогите мне с этим. – tusar

ответ

4

Gotcha !!! Я решил проблему с JSONP и вызовом jQuery AJAX.Я обнаружил атрибут timeout jQuery AJAX, и мой код выполнялся плавно, когда порт был заблокирован или открыт. Вот решение для будущих посетителей. Спасибо всем ответчикам за вклад.

<!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

Отлично! Я почти уверен, что этот вариант «тайм-аута» реализован благодаря JS «setTimeout» –

+0

спасибо за указание, и я рад, что все видят это как «лучший ответ», который является правильным, точным и понятным нет скрытой информации, как другие ответы, половина в умах, половина комментариев ... какой беспорядок! Я не буду забывать о такой постыдной ситуации на SO. – tusar

+0

Я согласен с вами. Я должен был взглянуть на мою идею «тайм-аута», которую я знаю из опыта JavaScript и Java в jQuery API, вместо того, чтобы следовать по пути других ответов ... Надеюсь, я тоже узнал об этом. –

2

Я не думаю, что вы понимаете варианты использования JSONP, и с ним невозможно проверить открытые порты. http://en.wikipedia.org/wiki/JSONP

Если вы хотите, чтобы клиентское решение было возможно с помощью websockets, но это доступно только для новых браузеров, таких как хром или ff. В противном случае запросите скрипт на стороне сервера, который выполняет пинг. Например, с помощью скручивания: curl and ping - how to check whether a website is either up or down?

+0

Я забыл пометить это с помощью java. Я не могу использовать «завиток». это PHP? простите меня, если я ошибаюсь. Любые другие решения? – tusar

+0

В Java вы можете значительно улучшить сетевые подключения с помощью класса URL или класса Socket: http://stackoverflow.com/questions/3584210/preferred-java-way-to-ping-a-http-url-for-availability –

+0

Ya , получил ваше мнение.см. код Java будет выполняться на сервере. правильно? где я всегда буду открывать порт. Но это проблема с клиентом, в сети которого порт может блокироваться. В этих случаях я не могу запустить что-либо, кроме JavaScript. – tusar

1

Вы не можете сделать это в JavaScript, потому что он не поддерживает настоящую поддержку сокетов, а с помощью JavaScript вы можете проверить только наличие HTTP-сокета. Вы можете использовать Java (JavaScript не Java) и написать соответствующий Java-апплет для этого.

Вы также должны прочитать это Q&A How to Ping in java

Попробуйте использовать isReachable

+0

во-первых, спасибо за ваше время. Никто не смотрит на это вообще ... так грустно. вы хотели бы дать мне пример апплета. Я попытался спроектировать один, но это приводит к беспорядку. Можете ли вы предоставить мне пример/ссылку? – tusar

+0

одно обновление, мой апплет дает правильный результат (о наличии порта) в апплетах, но в браузере его результаты кэширования я предполагаю. любое предложение ? – tusar

+0

привет, я обновил вопрос с результатами, не могли бы вы посмотреть? – tusar

0

В JavaScript, вы должны работать вокруг асинхронного выпуска. Вот предложение:

  • HTML-страница отображается анимированное изображение в качестве индикатора выполнения
  • вы вызываете checkURL
  • После либо получения обратного вызова или определенный тайм-аут, можно изменить отображение сообщения об ошибке или делать дальше с работой, чтобы сделать

Основываясь на following document с использованием XMLHttpRequest, вот пример кода для 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 

Этот код позволяет 1 секунде получить ответ 200 из HTTP GET на базовом ресурсе.

В вашем местном тесте вы получите немедленный ответ, потому что система отвечает connection reset, если порт закрыт, но брандмауэр просто не отвечает.

Даже если метод open может использоваться синхронно, я рекомендую использовать таймер, потому что код может ожидания для TCP тайм-аута и повторных попыток (3 х 1 минуту?) Как брандмауэр обычно просто отбрасывает пакеты на закрытые порты и могут отклонять пакеты ICMP, что препятствует проверке доступности благодаря ping. И я предполагаю, что такого долгого ожидания не ожидается для такой проверки.

+0

Я думаю, что тайм-аут может и не быть хорошей идеей. Я попробую JSON-P (как я указал, мне нужен кросс-домен). Вернемся к вам очень скоро. Спасибо за ваше время. – tusar

+0

Почему «не очень хорошая идея»? Это достаточно далеко, чтобы проверить доступность сервера/порта. Я использовал такой код для сложного html/javascript-клиента для поддержки онлайн-режима в автономном режиме с регулярными попытками подключения и индикатором выполнения для пользователя ... Поэтому, пожалуйста, рассмотрите его и проверьте –

1

Вместо апплета может использоваться вспышка. Используя класс Socket, доступный в ActionCcript, можно открыть tcp-соединение из флэш-памяти на порт на сервере, чтобы проверить, открыт ли он. Но на основе версии flash-плеера файл политики должен быть размещен на сервере, к которому открыт сокет.

+0

привет Али, я не делаю флеш-файлы. Не могли бы вы поделиться им, если у вас есть? Я думаю, что это должен быть лучший способ сделать это. – tusar

+0

привет, я обновил вопрос с результатами, не могли бы вы посмотреть? – tusar

2

Вот код Java как апплет для проверки подключения сервера/порт:

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

Вы все еще должны получить информацию из апплета, чтобы сделать что-то еще с этим результатом. Самый простой способ для перенаправления браузера благодаря getAppletContext().showDocument(url)

+0

привет Мартин, я пробовал это и обновил вопрос с результатами, не могли бы вы посмотреть? – tusar

1

Проверьте это:

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

С JS-Recon, вы можете сделать сканирование портов с помощью JavaScript. Вы можете просто указать его на локальный IP-адрес. Я считаю, что это работает, создавая соединение с веб-сокетами/cors с произвольным дескриптором ip/socket и измеряя таймауты. Это не идеальный подход, но в конечном итоге это может быть предел javascript.

Если вы можете сделать это в апплете java/flash-приложении, это может быть лучше, поскольку они имеют доступ на нижнем уровне.

+0

Клянусь, я не слышал об этом раньше. И спасибо за хорошие идеи в последнем параграфе. Конечно, я посмотрю эти API. Большое спасибо. И если вам интересно посмотреть, как я решил свою проблему, см. Мой собственный ответ! – tusar

Смежные вопросы