如何检查客户端的网络/防火墙是不是打开端口?
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 的编辑
【讨论】:
以上是关于如何检查客户端的网络/防火墙是不是打开端口?的主要内容,如果未能解决你的问题,请参考以下文章
外网无法访问VM中的hadoop yarn的8088端口,网页打开不了