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

时间:2012-01-20 05:33:18

标签: java javascript jquery java-ee jsonp

  

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

请参阅更新的部分,我也尝试过applet。如果您能通过applet实施提供解决方案,我们会毫不犹豫地接受您的回答。

我正在使用基于Java的Web应用程序。我的要求是检查特定端口(例如1935)是否在客户端打开或阻止。我已经实现了一个“jsonp”(为什么'jsonp'?我发现通过AJAX的'http'请求不能用于corssdomain for browsers'相同的原始策略')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
}

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

我尝试使用Java Applet(感谢Y Martin的建议)。这在appletviewer中运行良好。但是当我在HTML页面中添加applet时,它会提供易受攻击的结果。从某种意义上说,当我更改选项卡或调整浏览器大小时,“portAvailable的值在打印的消息中会被更改”。

Applet代码:

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页面(我在同一台计算机上托管它,并在端口9090上运行不同的Tomcat 6.我可以使用url ---> http://101.220.25.76:9090/test/查看此页面):

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

我是如何进行端口1935阻止和打开的?

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

这是我的S.S.C.C.E。现在请帮助我:))

8 个答案:

答案 0 :(得分:4)

得了!!!我用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>

答案 1 :(得分:2)

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

如果您需要客户端解决方案,可以使用websockets,但这仅适用于chrome或ff等新浏览器。否则请求执行ping的服务器端脚本。例如 - 使用curl脚本:curl and ping - how to check whether a website is either up or down?

答案 2 :(得分:2)

这是一个Java代码,作为测试服务器/端口连接的Applet:

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

您仍然必须从applet中获取信息,以便对该结果执行其他操作。最简单的方法是通过getAppletContext().showDocument(url)

重定向浏览器

答案 3 :(得分:1)

您无法在JavaScript中执行此操作,因为它没有真正的套接字支持,使用JavaScript只能测试是否存在HTTP套接字。您可以使用Java(JavaScript不是Java)并编写适当的Java Applet来完成它。

您还应该阅读此Q&A How to Ping in java

尝试使用isReachable

答案 4 :(得分:1)

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

答案 5 :(得分:1)

检查出来:

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

使用JS-Recon,您可以使用javascript进行端口扫描。您只需将其指向您的本地IP地址即可。我相信它的工作原理是将一个web套接字/ cors连接到一个任意的desintation ip / socket并测量超时。这不是一个完美的方法,但这最终可能是javascript的限制。

如果您可以在Java applet / flash应用程序中执行此操作,那么最终可能会更好,因为它们具有较低级别的访问权限。

答案 6 :(得分:0)

在JavaScript中,您必须解决异步问题。这是一个提案:

  • HTML页面将动画图像显示为进度条
  • 您调用checkURL
  • 收到回调或定义的超时后,您更改显示错误消息或继续执行作业

基于使用XMLHttpRequest的{​​{3}},以下是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秒钟从基本资源上的HTTP GET获得200响应。

在本地测试中,您会立即得到答案,因为如果端口已关闭但防火墙无法应答,则系统会回答连接重置

即使可以同步使用open方法,我建议使用计时器,因为代码可能等待TCP超时并重试(3 x 1分钟?)因为防火墙通常只会丢弃封闭端口上的数据包,并且可能会拒绝ICMP数据包,因此无法通过 ping 来测试可用性。我想这样的检查不会有这么长时间的等待。

答案 7 :(得分:0)

我偶尔是frontend / javascript / jQuery家伙,所以这可能不是100%专业,但这已经足够好了,它解决了我类似的问题:

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

由于视图已被缓存,我无法在服务器端检查端口是否已打开(桌面应用程序正在运行),因此我需要在用户单击浏览器之前先检查localhost /端口。

欢迎翻译成JS