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

Posted

技术标签:

【中文标题】如何检查客户端的网络/防火墙是不是打开端口?【英文标题】:How to check whether a port is open at client's network/firewall?如何检查客户端的网络/防火墙是否打开端口? 【发布时间】:2012-01-20 05:33:18 【问题描述】:

这最终通过 jQuery AJAX(和 JSONP)的“超时”属性解决。看我自己的答案!

请看更新的部分,我也试过用applet。如果您可以提供小程序实现的解决方案,将毫不犹豫地接受您的回答。

我正在使用基于 Java 的 Web 应用程序。我的要求是检查特定端口(比如 1935)在客户端是打开还是阻塞。我已经实现了“jsonp”(为什么是“jsonp”?我发现通过 AJAX 的“http”请求不能用于浏览器“同源策略”的 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 Applet(感谢 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 托管它,该 Tomcat 6 在端口 9090 上运行。我可以使用 url 查看此页面 ---> @987654321@):

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

我是怎么做 1935 端口的阻塞和打开的?

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

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

【问题讨论】:

您的代码不仅会测试“端口”是否打开,还会测试是否有服务器响应 HTTP 请求。您的代码需要在浏览器中运行吗?可能是 Java 小程序适合您的解决方案? Applet 是一个选项,这取决于浏览器的 java 插件的可用性,我想避免这种情况。我已经设置了一个在端口 1935 上应答的服务器,无论协议是什么(是的,它是 HTTP)。我也收到回复(当端口打开时)。但是,如果端口在客户端被阻塞,我该如何收听呢?这就是重点 @YvesMartin,您能否发布有关小程序或任何其他实现的答案?是的,我希望代码在浏览器上执行。请帮我解决这个问题。 无法想象即使问题被其他人收藏,人们也会投减票,请投反对票的人说出他的理由,以便我改进帖子吗? 真诚更新后的小程序代码……比以前更不清晰了。 “我如何阻止/打开 1935 端口”是什么意思。你确定这仍然是同一个问题吗? Applet 中的硬编码值是否存在问题 - 如果是这样,有一种方法可以将参数从 HTML 传递到 Applet。如果您收到诸如安全异常之类的错误消息,请告诉我们 - 您必须使用证书对其进行签名。如果您想对测试结果做出反应,我建议您调用“showDocument”来重定向浏览器页面。 【参考方案1】:

明白了!我已经解决了 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>

【讨论】:

太棒了!我几乎可以肯定这个“超时”选项是通过 JS“setTimeout”实现的 我同意你的看法。我应该看看我从 JavaScript 和 Java 经验中了解到的“超时”想法到 jQuery API,而不是遵循其他答案的路径......我希望我也了解了它。 我建议您从小程序代码中清理您的问题以供将来的读者使用【参考方案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?

【讨论】:

我忘了用 java 标记这个。我不能使用curl。那是php对吗?如果我错了,请原谅我。还有其他解决方案吗? 在 Java 中,您可以使用 URL 或 Socket 类进行更好的网络连接:***.com/questions/3584210/… 是的,明白了。查看 Java 代码将在服务器中执行。对?我将永远打开端口。但这是客户端的问题,端口可能在其网络中阻塞。在这些情况下,除了 JavaScript,我什么都不能运行。 尝试运行一台可以访问所有系统的服务器,该服务器应该检查端口。然后,客户端可以在端口 80 (http) 上连接此服务器,并获取有关其他服务器的信息(端口可用性)。然后,服务器就像端口信息的代理。 嗨,Soc,看,我会设置另一台服务器。这将保存端口信息。好的。现在客户端将调用该服务器以获取端口 80 上的信息。它会发现,是的,端口 1935 在该特定代理服务器上是打开的。但我需要找到它是否在 clients network 中打开。【参考方案3】:

这是一个作为 Applet 测试服务器/端口连接性的 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)

【讨论】:

嗨马丁,我已经尝试过这个并用结果更新了问题,你能看看吗?【参考方案4】:

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

【讨论】:

嗨阿里,我不做闪存文件。有的话可以分享一下吗?我认为这些应该是做到这一点的最佳方式。 嗨,我已经用结果更新了问题,你能看看吗?【参考方案5】:

看看这个:

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

使用 JS-Recon,您可以使用 javascript 进行端口扫描。您可以简单地将其指向您的本地 IP 地址。我相信它可以通过与任意目的地 ip/socket 建立 Web 套接字/cors 连接并测量超时来工作。这不是一个完美的方法,但这最终可能是javascript的极限。

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

【讨论】:

我发誓我以前没有听说过。并感谢上一段中的好主意。当然,我会看看这些 API。非常感谢你。如果您有兴趣了解我是如何解决我的问题的,请查看我自己的答案!【参考方案6】:

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

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

尝试使用isReachable

【讨论】:

首先感谢您的宝贵时间。根本没有人在看这个……太伤心了。你想给我一个小程序的例子。我确实尝试过设计一个,但结果一团糟。你能给我一个例子/参考吗? 一个更新,我的小程序在小程序查看器中给出了正确的结果(关于端口的可用性),但我猜在浏览器中它的缓存结果。有什么建议吗? 嗨,我已经用结果更新了问题,你能看看吗?【参考方案7】:

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

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

基于following document和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 秒时间从基本资源上的 HTTP GET 获得 200 响应。

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

即使open 方法可以同步使用,我还是建议使用计时器,因为代码很可能会等待 TCP 超时并重试(3 x 1 分钟?)作为防火墙通常只丢弃关闭端口上的数据包,并可能拒绝 ICMP 数据包,由于 ping 而阻止您测试可用性。而且我想这样的检查不需要等待这么长时间。

【讨论】:

我认为超时可能不是一个好主意。我将尝试使用 JSON-P(因为我指定我需要跨域)。很快就会回复你。感谢您的宝贵时间。 为什么“不是一个好主意”?足以测试服务器/端口的可用性。我已经将这样的代码用于复杂的 html/javascript 客户端,以支持在线/离线模式,并为用户提供定期连接重试和进度条......所以请考虑并测试【参考方案8】:

我偶尔是前端/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")

由于视图被缓存,我无法在服务器端检查端口是否打开(桌面应用程序正在运行),所以我需要在用户点击浏览器之前检查本地主机/端口

欢迎翻译成 JS 的编辑

【讨论】:

以上是关于如何检查客户端的网络/防火墙是不是打开端口?的主要内容,如果未能解决你的问题,请参考以下文章

RTX2010服务器端的主要通信端口有哪些?

websock第一次连不上window

外网无法访问VM中的hadoop yarn的8088端口,网页打开不了

电脑用户必须要了解的几种木马

客户端的SoftEther连接不上!!!请教各位SoftEther高手!

服务器应用程序如何检查客户端应用程序是不是在线?