如何检查客户端网络/防火墙的端口是否打开?

时间:2022-07-06 07:22:54

This is solved at last with "timeout" attribute of jQuery AJAX (and JSONP). See my own answer !

最后用jQuery AJAX(和JSONP)的“timeout”属性解决了这个问题。看我自己的答案!

Please see the updated part, I have tried with applet too. And will not hesitate to accept your answer if you can give a solution with applet implementation.

请看更新的部分,我也试用过applet如果您能提供一个带有applet实现的解决方案,我们将毫不犹豫地接受您的回答。

I am working with a Java based web application. My requirement is to check whether a particular port (say 1935) is open or blocked at client's end. I have implemented a "jsonp" (why 'jsonp' ? i found that 'http' request through AJAX cannot work for corssdomain for browsers 'same origin policy') AJAX call to one of my server containing particular port. And if the server returns xhr.status == 200 the port is open. Here is a drawback that I can't make the execution-flow wait (synchronous) until the call completes. Here is the JavaScript function I am using.

我正在使用一个基于Java的web应用程序。我的要求是检查某个端口(比如1935)在客户端是打开的还是阻塞的。我实现了一个jsonp(为什么是jsonp) ?我发现,通过AJAX发出的“http”请求不能用于corssdomain,也不能用于浏览器的“同源策略”)。如果服务器返回xhr。端口是打开的。这里有一个缺点,在调用完成之前,我不能让执行流等待(同步)。这是我正在使用的JavaScript函数。

Any alternative solution (must be a client-sided thing must be parallel with my application, please dont suggest python/php/other languages) is also welcome. Thanks for your time.

任何替代的解决方案(必须是客户端方面的,必须与我的应用程序并行,请不要建议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
}

---------------------------------------------------------UPDATE----------------------------------------------------------------

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - update - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

I have tried with Java Applet (thanks to Y Martin's suggestion). This is working fine in appletviewer. But when I add the applet in HTML page, it is giving vulnerable results. Vulnerable in the sense, when I change the tab or resize the browser, the value of portAvailable is being altered in the printed message.

我尝试过Java Applet(感谢Y Martin的建议)。这在appletviewer中运行良好。但是当我在HTML页面中添加applet时,它会给出脆弱的结果。在某种意义上来说,当我更改选项卡或调整浏览器的大小时,在打印的消息中会更改portAvailable的值。

Applet Code :

小应用程序代码:

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

And this is my HTML page (I am hosting it on same computer with a different Tomcat 6 which runs on port 9090. I can view this page with url ---> http://101.220.25.76:9090/test/):

这是我的HTML页面(我在同一台计算机上托管它,并在端口9090上运行不同的Tomcat 6。我可以使用url --> http://101.220.25.76:9090/test/)查看此页面:

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

And how I am doing the port 1935 blocking and openning ?

我怎么做1935年的港口*和开放?

I have created firewall rule for both inbound and outbound for port 1935. I check the port 1935 open/blocked scenario by disabling/enabling both rules.

我为1935端口的入站和出站创建了防火墙规则。我通过禁用/启用这两个规则检查1935端口打开/阻塞场景。

This is my S.S.C.C.E. Now please help me :)

这是我的s.c.c.e.,请帮我一下。

7 个解决方案

#1


4  

Gotcha !!! I have solved my problem with JSONP and jQuery AJAX call. I discovered the timeout attribute of jQuery AJAX and my code executed fluently when the port was blocked or opened. Here is the solution for future visitors. Thanks to all answerers for contribution.

明白了! ! !我已经解决了JSONP和jQuery AJAX调用的问题。我发现jQuery AJAX的timeout属性和我的代码在端口被阻塞或打开时能够流畅地执行。这是未来游客的解决方案。感谢所有人的贡献。

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


2  

I don't think you understand the use cases for JSONP and it's not possible to test open ports with it. http://en.wikipedia.org/wiki/JSONP

我认为您不理解JSONP的用例,也不可能用它测试开放端口。http://en.wikipedia.org/wiki/JSONP

If you want a client side solution it could be possible with websockets, but this is only available on new browsers like chrome or ff. Otherwise request a server side script which does the ping. For example - with a curl script: curl and ping - how to check whether a website is either up or down?

如果您想要客户端解决方案,可以使用websockets,但这只能在新的浏览器上使用,如chrome或ff。否则请求执行ping的服务器端脚本。例如-使用curl脚本:curl和ping -如何检查一个网站是向上还是向下?

#3


2  

Here is a Java code as an Applet to test server/port connectivity:

这里有一个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);
    }
}

You still have to get the information out of the applet to do something else with that result. The easiest way is to redirect the browser thanks to getAppletContext().showDocument(url)

您仍然需要从applet中获取信息,以便对结果进行其他操作。最简单的方法是通过getAppletContext().showDocument(url)重定向浏览器

#4


1  

Instead of an applet a flash component may be used. Using the Socket class available in ActionCcript one can open a tcp connection from flash to a port on a server to check if its open. But based on the flash player version a policy file needs to be placed on the server to which the socket is opened.

可以使用flash组件代替applet。使用ActionCcript中提供的套接字类,可以打开从flash到服务器端口的tcp连接,检查它是否打开。但是基于flash player版本,需要在打开套接字的服务器上放置策略文件。

#5


1  

Check this out:

看看这个:

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

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

With JS-Recon, you can do port scanning with javascript. You can simply point it to your local IP address. I believe it works by making a web sockets/cors connection to an arbitrary desintation ip/socket and measuring the timeouts. It is not a perfect approach, but this may be the limit of javascript ultimately.

使用JS-Recon,您可以使用javascript执行端口扫描。您可以简单地将它指向您的本地IP地址。我相信它通过将web套接字/cors连接到任意的去调ip/套接字并测量超时来工作。这不是一种完美的方法,但这可能是javascript的最终限制。

If you can do it in a java applet/flash application, that may be better ultimately as they have lower-level access.

如果您可以在java applet/flash应用程序中完成,那么最终可能会更好,因为它们的访问级别较低。

#6


1  

You cannot do this in JavaScript because it doesn't have true socket support, with JavaScript you can only test for the presence of HTTP socket. You could use Java (JavaScript is not Java) and write a proper Java Applet to do it.

在JavaScript中不能这样做,因为它没有真正的套接字支持,使用JavaScript只能测试HTTP套接字的存在。您可以使用Java (JavaScript不是Java)并编写一个合适的Java Applet来实现它。

You should also read this Q&A How to Ping in java

您还应该阅读这个Q&A如何在java中Ping。

Try using isReachable

试着用isReachable

#7


0  

In JavaScript, you have to work-around the asynchronous issue. Here is a proposal:

在JavaScript中,您必须解决异步问题。这里有一个建议:

  • The HTML page displays an animated image as a progress bar
  • HTML页面显示一个动画图像作为进度条
  • You invoke the checkURL
  • 你调用checkURL
  • After either receiving the callback or a defined timeout, you change display for an error message or do on with the job to do
  • 在接收回调或定义的超时之后,您可以更改错误消息的显示,或者继续执行要执行的任务

Based on the following document with the use of XMLHttpRequest, here is a code example for 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 

This code lets 1 second to get the 200 response from a HTTP GET on a basic resource.

这段代码允许1秒钟从HTTP get获得200个响应。

In your local test, you get an immediate answer because the system answers connection reset if the port is closed but a firewall just does not answer.

在您的本地测试中,您将得到一个立即的答案,因为如果端口被关闭,但是防火墙没有应答,那么系统将回复连接重置。

Even if the open method may be used synchronously, I recommend the use of a timer because the code is likely to wait for TCP timeouts and retries (3 x 1 minute ?) as a firewall usually just drops packets on closed ports and may reject ICMP packets, preventing you to test availability thanks to ping. And I imagine such a long wait is not expected for such a check.

即使开放同步方法可以使用,我建议使用一个计时器,因为代码可能会等待TCP超时和重试(3 x 1分钟?)作为防火墙通常只是滴包5月关闭港口和拒绝ICMP数据包,防止由于萍你测试可用性。我想这样的长时间等待是不可能的。

#1


4  

Gotcha !!! I have solved my problem with JSONP and jQuery AJAX call. I discovered the timeout attribute of jQuery AJAX and my code executed fluently when the port was blocked or opened. Here is the solution for future visitors. Thanks to all answerers for contribution.

明白了! ! !我已经解决了JSONP和jQuery AJAX调用的问题。我发现jQuery AJAX的timeout属性和我的代码在端口被阻塞或打开时能够流畅地执行。这是未来游客的解决方案。感谢所有人的贡献。

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


2  

I don't think you understand the use cases for JSONP and it's not possible to test open ports with it. http://en.wikipedia.org/wiki/JSONP

我认为您不理解JSONP的用例,也不可能用它测试开放端口。http://en.wikipedia.org/wiki/JSONP

If you want a client side solution it could be possible with websockets, but this is only available on new browsers like chrome or ff. Otherwise request a server side script which does the ping. For example - with a curl script: curl and ping - how to check whether a website is either up or down?

如果您想要客户端解决方案,可以使用websockets,但这只能在新的浏览器上使用,如chrome或ff。否则请求执行ping的服务器端脚本。例如-使用curl脚本:curl和ping -如何检查一个网站是向上还是向下?

#3


2  

Here is a Java code as an Applet to test server/port connectivity:

这里有一个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);
    }
}

You still have to get the information out of the applet to do something else with that result. The easiest way is to redirect the browser thanks to getAppletContext().showDocument(url)

您仍然需要从applet中获取信息,以便对结果进行其他操作。最简单的方法是通过getAppletContext().showDocument(url)重定向浏览器

#4


1  

Instead of an applet a flash component may be used. Using the Socket class available in ActionCcript one can open a tcp connection from flash to a port on a server to check if its open. But based on the flash player version a policy file needs to be placed on the server to which the socket is opened.

可以使用flash组件代替applet。使用ActionCcript中提供的套接字类,可以打开从flash到服务器端口的tcp连接,检查它是否打开。但是基于flash player版本,需要在打开套接字的服务器上放置策略文件。

#5


1  

Check this out:

看看这个:

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

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

With JS-Recon, you can do port scanning with javascript. You can simply point it to your local IP address. I believe it works by making a web sockets/cors connection to an arbitrary desintation ip/socket and measuring the timeouts. It is not a perfect approach, but this may be the limit of javascript ultimately.

使用JS-Recon,您可以使用javascript执行端口扫描。您可以简单地将它指向您的本地IP地址。我相信它通过将web套接字/cors连接到任意的去调ip/套接字并测量超时来工作。这不是一种完美的方法,但这可能是javascript的最终限制。

If you can do it in a java applet/flash application, that may be better ultimately as they have lower-level access.

如果您可以在java applet/flash应用程序中完成,那么最终可能会更好,因为它们的访问级别较低。

#6


1  

You cannot do this in JavaScript because it doesn't have true socket support, with JavaScript you can only test for the presence of HTTP socket. You could use Java (JavaScript is not Java) and write a proper Java Applet to do it.

在JavaScript中不能这样做,因为它没有真正的套接字支持,使用JavaScript只能测试HTTP套接字的存在。您可以使用Java (JavaScript不是Java)并编写一个合适的Java Applet来实现它。

You should also read this Q&A How to Ping in java

您还应该阅读这个Q&A如何在java中Ping。

Try using isReachable

试着用isReachable

#7


0  

In JavaScript, you have to work-around the asynchronous issue. Here is a proposal:

在JavaScript中,您必须解决异步问题。这里有一个建议:

  • The HTML page displays an animated image as a progress bar
  • HTML页面显示一个动画图像作为进度条
  • You invoke the checkURL
  • 你调用checkURL
  • After either receiving the callback or a defined timeout, you change display for an error message or do on with the job to do
  • 在接收回调或定义的超时之后,您可以更改错误消息的显示,或者继续执行要执行的任务

Based on the following document with the use of XMLHttpRequest, here is a code example for 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 

This code lets 1 second to get the 200 response from a HTTP GET on a basic resource.

这段代码允许1秒钟从HTTP get获得200个响应。

In your local test, you get an immediate answer because the system answers connection reset if the port is closed but a firewall just does not answer.

在您的本地测试中,您将得到一个立即的答案,因为如果端口被关闭,但是防火墙没有应答,那么系统将回复连接重置。

Even if the open method may be used synchronously, I recommend the use of a timer because the code is likely to wait for TCP timeouts and retries (3 x 1 minute ?) as a firewall usually just drops packets on closed ports and may reject ICMP packets, preventing you to test availability thanks to ping. And I imagine such a long wait is not expected for such a check.

即使开放同步方法可以使用,我建议使用一个计时器,因为代码可能会等待TCP超时和重试(3 x 1分钟?)作为防火墙通常只是滴包5月关闭港口和拒绝ICMP数据包,防止由于萍你测试可用性。我想这样的长时间等待是不可能的。