7

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

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
tusar
  • 3,364
  • 6
  • 37
  • 60
  • 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 Apr 04 '12 at 06: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 Apr 04 '12 at 06: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 Apr 05 '12 at 08: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 Apr 08 '12 at 06: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 Apr 08 '12 at 07:27
  • Hi Martin, I have just simply added the applet in HTML page. I dont know why are you suggesting the redirection and showDocument. I just want to print the message whether the port is blocked or not in the html page by executing the applet. I dont want redirection, I dont want hardcoded values to pass. – tusar Apr 08 '12 at 07:40
  • The "how I am doing the port 1935 blocking/opening" meant for helping the users who wants to reproduce the problem on their own computers. and to give the reader a clear idea how I am creating the environment for testing the (when port is open/and when it is blocked). – tusar Apr 08 '12 at 07:43
  • The "wrong" thing is, applet is printing correct message in appletviewer. But in HTML page, when I resize the browser, the message value is changing from true->false and false -> true. It is not giving correct value about availability of port. No EXcepttions, no error message. Nothing to hide from readers. – tusar Apr 08 '12 at 07:48
  • The resize may reload the applet... You should not use a static variable. Generally (it depends on Java plugin implementation) there is one applet instance with its own thread on each page. The "paint" event may execute before the socket connection test is over... – Yves Martin Apr 09 '12 at 07:39
  • using non-static and local variable also resulted the same @Martin, I wish I could accept your Applet implementation. But it was acting really vulnerable. – tusar Apr 09 '12 at 07:41
  • The problem is the paint method for display. Have you tested the JavaScript version ? I have not answered about why a JS timeout is a "bad idea"... – Yves Martin Apr 09 '12 at 09:17
  • @Martin **Regarding the "bad idea" answer**-> Give me a cross-domain classic AJAX implementation which works on cross browser, then I will give a try. **Regarding Applet's paint method**-> Are those implementations really tried by reproducing the scenario ? How about you reproduce the scenario and try your own answers ? I have no issue with accepting the answer which is correct and vote up useful. BTW, just saw my total vote cast is 189, yours is 29. – tusar Apr 09 '12 at 09:28
  • It takes too much time to "reproduce the scenario": two tomcat servers, firewall rules... What is the most likely to happen is a "SecurityException" at line "Threw error" when trying to connect to another other compared to the one delivering the applet. Have you signed your Applet ? – Yves Martin Apr 09 '12 at 12:27
  • Great total vote cast, congratulations ! Until now, I have earned 15 bounties to a total of 925 rep. I hope your bounty will increase that score. – Yves Martin Apr 09 '12 at 12:33
  • you are on @Martin, thanks for helping so much :) – tusar Apr 09 '12 at 13:06

8 Answers8

5

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>
tusar
  • 3,364
  • 6
  • 37
  • 60
  • Great ! I am almost sure this "timeout" option is implemented thanks to a JS "setTimeout" – Yves Martin Apr 09 '12 at 12:30
  • I agree with you. I should have looked at my "timeout" idea I know from JavaScript and Java experience into jQuery API, instead of following the path of other answers... I hope I have learnt about it too. – Yves Martin Apr 09 '12 at 19:26
  • I propose you clean up your question from the applet code for future readers – Yves Martin Apr 09 '12 at 19:31
2

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)

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
  • hi Martin, I have tried this and updated the question with results, could you please have a look ? – tusar Apr 08 '12 at 06:16
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

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?

Community
  • 1
  • 1
Sebastian Stiehl
  • 1,880
  • 1
  • 14
  • 22
  • I forgot to tag this with java. I cant use `curl`. that is PHP right ? pardon me if I am wrong. Any other solutions ? – tusar Apr 01 '12 at 19:09
  • In Java you can do much better network connections with the URL or Socket class: http://stackoverflow.com/questions/3584210/preferred-java-way-to-ping-a-http-url-for-availability – Sebastian Stiehl Apr 01 '12 at 19:21
  • Ya, got your point. see the Java code will be executed in server. right? where I will always open the port. But it is the problem with client, in whose network the port may blocked. In those cases, I cant run anything except JavaScript. – tusar Apr 01 '12 at 19:25
  • 1
    Try to run one server which has access to all systems where the port should be checked. The clients can then connect against this server on port 80 (http) an get the information about the other servers (port availability). The server is then like a proxy for the port information. – Sebastian Stiehl Apr 01 '12 at 19:40
  • Hi Soc, see, I would setup another server. This will hold the port information. OK. Now the client will call this server for imformation on port 80. It will find, ya, port 1935 is open *on that particular proxy server*. But I need to find, whether it is open or not in *clients network*. – tusar Apr 02 '12 at 06:08
  • Please check if you have any other idea... Im scratching my head with this since long. Will be thankful to you if you can help me with this. – tusar Apr 02 '12 at 06:13
  • hi,I have updated the question with results, could you please have a look ? – tusar Apr 08 '12 at 06:19
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.

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

Try using isReachable

Community
  • 1
  • 1
Martin Spamer
  • 5,437
  • 28
  • 44
  • firstly thanks for your time. No one is looking at this at all... so sad. would you like to give me an applet example. I did try to design one, but it is resulting in a mess. Can you please provide me an example/reference ? – tusar Apr 05 '12 at 12:39
  • one update, my applet is giving correct result (about availability of port) in applet-viewer, but in browser its caching results I guess. any suggestion ? – tusar Apr 06 '12 at 05:35
  • hi,I have updated the question with results, could you please have a look ? – tusar Apr 08 '12 at 06:17
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.

Ali
  • 289
  • 1
  • 3
  • hi Ali, I dont do flash files. Could you please share if you have one ? I think these should be the best way to do this. – tusar Apr 06 '12 at 08:04
  • hi,I have updated the question with results, could you please have a look ? – tusar Apr 08 '12 at 06:18
1

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.

badunk
  • 4,310
  • 5
  • 27
  • 47
  • I swear I didnt heard about that before. And thanks for the good ideas in last para. Surely I will have a look at those APIs. Thank you very much. And if you are interested to see how did I solve my problem, see my own answer ! – tusar Apr 08 '12 at 20:02
0

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.

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
  • I think timeout may not be a good idea. I will give this a try with JSON-P (as I specified I need cross-domain). Will get back to you very soon. thanks for your time. – tusar Apr 06 '12 at 06:26
  • Why "not a good idea" ? It is far enough to test server/port availability. I have used such code for a complex html/javascript client to support online/offline mode with regular connection retries and progress bar for user... So please consider it and test – Yves Martin Apr 06 '12 at 13:21
0

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

ToTenMilan
  • 582
  • 1
  • 9
  • 19