admin管理员组

文章数量:1201993

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

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.

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.

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.

function checkURL() {

    var url = ":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----------------------------------------------------------------

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.

Applet Code :

import java.applet.Applet;
import java.awt.Graphics;
import java.InetSocketAddress;
import java.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>
<body>
        <applet code="ConnectionTestApplet" width=300 height=50>
        </applet>
</body>
</html>

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

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.

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

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

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.

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.

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.

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

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.

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>
<body>
        <applet code="ConnectionTestApplet" width=300 height=50>
        </applet>
</body>
</html>

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

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.

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

Share Improve this question edited Aug 19, 2015 at 18:50 community wiki
20 revs, 2 users 71%
tusar 15
  • 1 Your code does not only test if the "port" is opened but also there is a server answering to HTTP request. Do your code need to run in a browser ? May be a Java applet a solution for you ? – Yves Martin Commented Apr 4, 2012 at 6:34
  • Applet is an option, that depends upon the availability of java plugin of browser, which I want to avoid. I have setup a server which is answering on port 1935 whatever be the protocol(yes it is HTTP). I am getting reply also (when port is open). But if the port is blocked on clients end, how do I listen to that? that is point – tusar Commented Apr 4, 2012 at 6:43
  • @YvesMartin, could you please post answer about applet or any other implementation ? Yes I want the code to be executed on browser. Please help me with this. – tusar Commented Apr 5, 2012 at 8:24
  • Cant imagine people doing minus vote even when the question is favorited by others, will the downvoter please express his reason so that I can improve the post ? – tusar Commented Apr 8, 2012 at 6:33
  • Sincerely after the update with applet code... it is even less clear than before. what does "how I am doing the port 1935 blocking/opening" mean. Are you sure it is still the same question ? Is the problem hardcoded values in Applet - if so, there is a way to pass parameters from HTML to Applet. If you got error messages like security exception, please tell us - you will have to sign it with a certificate. If you want to react to test result, I have recommended you to invoke "showDocument" to redirect the browser page. – Yves Martin Commented Apr 8, 2012 at 7:27
 |  Show 10 more comments

8 Answers 8

Reset to default 6

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.

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

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

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?

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

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)

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.

Check this out:

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.

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

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.

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

Try using isReachable

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

  • The HTML page displays an animated image as a progress bar
  • You invoke the 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:

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.

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.

I am occasional frontend/javascript/jQuery guy, so this may not be 100% professional, but it is good enough and it solved my similar problem:

ping_desktop_app = $.get({
  url: "http://127.0.0.1:#{desktop_app_port}",
  dataType: 'jsonp',
})

$(@).parent().find(".click-me-to-use-desktop-app").click ->
  if ping_desktop_app.status == 200
    $.get({
      url: "http://127.0.0.1:#{desktop_app_port}/some_command/123123",
      dataType: 'jsonp',
    })
  else
    alert("Please run your desktop app and refresh browser")

I could not check whether port is open (desktop app is running) on server side because views are cached, so I needed to check the localhost/port right before user click in browser

Edits translating to JS are welcome

本文标签: javaHow to check whether a port is open at client39s networkfirewallStack Overflow