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

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

请参阅更新的部分,我也尝试过applet。 如果您能通过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 } 

————————————————– ——- UPDATE —————————————— ———————-

我尝试过使用Java Applet(感谢Y Martin的建议)。 这在appletviewer中工作正常。 但是当我在HTML页面中添加applet时,它会提供易受攻击的结果。 从某种意义上说,当我更改选项卡或调整浏览器大小时, 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页面(我在同一台计算机上托管它,并在端口9090上运行不同的Tomcat 6.我可以使用url查看此页面—> http://101.220.25.76:9090/test/ ):

       

我是如何做端口1935阻塞和开放的?

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

这是我的SSCCE 。 现在请帮帮我:)

得到!!! 我用JSONP和jQuery AJAX调用解决了我的问题。 我发现了jQuery AJAX的timeout属性,当端口被阻塞或打开时,我的代码流畅地执行。 这是未来访客的解决方案。 感谢所有回复者的贡献。

           

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

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

这是一个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)重定向浏览器getAppletContext().showDocument(url)

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

看一下这个:

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应用程序中执行此操作,那么最终可能会更好,因为它们具有较低级别的访问权限。

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

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

尝试使用isReachable

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

  • HTML页面将动画图像显示为进度条
  • 你调用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 

此代码允许1秒钟从基本资源上的HTTP GET获取200响应。

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

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