Как проверить, открыт ли порт в клиентской сети / брандмауэре? - PullRequest
5 голосов
/ 20 января 2012

Наконец, это решается с помощью атрибута "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 Martin). Это нормально работает в appletviewer. Но когда я добавляю апплет на HTML-страницу, он дает уязвимые результаты. Уязвимый в том смысле, что при изменении вкладки или изменении размера браузера значение portAvailable изменяется в печатном сообщении.

Код апплета:

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 ---> <a href="http://101.220.25.76:9090/test/" rel="nofollow">http://101.220.25.76:9090/test/</a>):

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

А как у меня порт 1935 блокируется и открывается?

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

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

Ответы [ 7 ]

4 голосов
/ 08 апреля 2012

Понял !!!Я решил мою проблему с вызовом 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>
2 голосов
/ 06 апреля 2012

Вот код 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)

2 голосов
/ 01 апреля 2012

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

Если вам нужно клиентское решение, это может быть возможно с веб-сокетами, но это доступно только в новых браузерах, таких как chrome или ff.В противном случае запросите серверный скрипт, который выполняет пинг.Например - с помощью скрипта curl: curl and ping - как проверить, работает ли сайт или нет?

1 голос
/ 08 апреля 2012

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

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

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

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

1 голос
/ 06 апреля 2012

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

1 голос
/ 05 апреля 2012

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

Вы также должны прочитать это Q & A Как пинговать в Java

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

0 голосов
/ 06 апреля 2012

В JavaScript вам нужно обойти асинхронную проблему. Вот предложение:

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

На основе следующего документа с использованием 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 для основного ресурса.

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

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

...