Как проверить, открыт ли порт в сети клиента/брандмауэре?

Это наконец-то решается с атрибутом "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" target="_blank">http://101.220.25.76:9090/test/</a>):

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

И как я делаю блокировку и открытие порта 1935?

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

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

7 ответов

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


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

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


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


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


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

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

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

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


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

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

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


В 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 на базовом ресурсе.

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

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

licensed under cc by-sa 3.0 with attribution.