[英]How to check whether a port is open at client's network/firewall?
这最终通过 jQuery AJAX(和 JSONP)的“超时”属性解决。 看我自己的回答!
请参阅更新的部分,我也尝试过使用小程序。 如果您可以提供带有小程序实现的解决方案,将毫不犹豫地接受您的回答。
我正在使用基于 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 ---> http://101.220.25.76:9090/test/
查看此页面):
<html>
<body>
<applet code="ConnectionTestApplet" width=300 height=50>
</applet>
</body>
</html>
我是如何阻止和打开 1935 端口的?
我为端口 1935 的入站和出站创建了防火墙规则。我通过禁用/启用这两个规则来检查端口 1935 打开/阻止的情况。
这是我的SSCCE 。 现在请帮助我:)
明白了!!! 我已经用 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>
这是一个 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);
}
}
您仍然必须从小程序中获取信息才能对结果执行其他操作。 最简单的方法是使用getAppletContext().showDocument(url)
重定向浏览器
我认为您不了解 JSONP 的用例,并且无法使用它来测试开放端口。 http://en.wikipedia.org/wiki/JSONP
如果您想要客户端解决方案,可以使用 websockets,但这仅适用于 chrome 或 ff 等新浏览器。 否则请求执行 ping 的服务器端脚本。 例如 - 使用 curl 脚本: curl 和 ping - 如何检查网站是启动还是关闭?
你不能在 JavaScript 中这样做,因为它没有真正的套接字支持,使用 JavaScript 你只能测试 HTTP 套接字的存在。 您可以使用 Java(JavaScript 不是 Java)并编写一个合适的 Java Applet 来完成它。
您还应该阅读这个Q&A How to Ping in java
尝试使用isReachable
可以使用 flash 组件代替小程序。 使用 ActionCcript 中可用的 Socket 类,可以打开从闪存到服务器端口的 tcp 连接,以检查其是否打开。 但是根据 Flash Player 版本,需要在打开套接字的服务器上放置一个策略文件。
看一下这个:
http://blog.andlabs.org/2010/12/port-scanning-with-html5-and-js-recon.html
使用 JS-Recon,您可以使用 javascript 进行端口扫描。 您可以简单地将其指向您的本地 IP 地址。 我相信它可以通过将网络套接字/cors 连接到任意目标 ip/socket 并测量超时来工作。 这不是一个完美的方法,但这最终可能是 javascript 的限制。
如果您可以在 java applet/flash 应用程序中执行此操作,那么最终可能会更好,因为它们具有较低级别的访问权限。
在 JavaScript 中,您必须解决异步问题。 这是一个提议:
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阻止您测试可用性。 我想这样的检查不会有这么长时间的等待。
我偶尔会做前端/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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.