我需要发现远程服务器上的开放端口。我想知道这是否可行。我在想我打开一个套接字,如果这个成功,就意味着它被使用了......否则,如果我得到一个异常,那么就不会使用它。
例如,
public boolean isActive() {
Socket s = null;
try {
s = new Socket();
s.setReuseAddress(true);
SocketAddress sa = new InetSocketAddress(this.host, this.port);
s.connect(sa, 3000);
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
}
}
}
return false;
}
这是一种可行的方法吗?
答案 0 :(得分:14)
FWIW,我经常使用的Java解决方案(优于telnet:支持超时)。
package com.acme.util;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
public class CheckSocket {
public static void main(String[] args) {
int exitStatus = 1 ;
if (args.length != 3) {
System.out.println("Usage: CheckSocket node port timeout");
} else {
String node = args[0];
int port = Integer.parseInt(args[1]);
int timeout = Integer.parseInt(args[2]);
Socket s = null;
String reason = null ;
try {
s = new Socket();
s.setReuseAddress(true);
SocketAddress sa = new InetSocketAddress(node, port);
s.connect(sa, timeout * 1000);
} catch (IOException e) {
if ( e.getMessage().equals("Connection refused")) {
reason = "port " + port + " on " + node + " is closed.";
};
if ( e instanceof UnknownHostException ) {
reason = "node " + node + " is unresolved.";
}
if ( e instanceof SocketTimeoutException ) {
reason = "timeout while attempting to reach node " + node + " on port " + port;
}
} finally {
if (s != null) {
if ( s.isConnected()) {
System.out.println("Port " + port + " on " + node + " is reachable!");
exitStatus = 0;
} else {
System.out.println("Port " + port + " on " + node + " is not reachable; reason: " + reason );
}
try {
s.close();
} catch (IOException e) {
}
}
}
}
System.exit(exitStatus);
}
}
答案 1 :(得分:3)
这是否必须用Java完成?有工具(Nmap)。否则,你的方法将“有效”,但我不确定这将有多大用处。
请注意,防火墙可以做一些棘手的事情。例如允许连接建立但不对其进行任何操作,因此看起来好像端口已打开但防火墙实际上阻止了所有流量。或者,某些端口仅对来自特定IP范围,子网或物理设备的请求开放。