Java 在*NIX上检测打开的端口时出现问题
我正在尝试编写一个程序,该程序将检测系统上所有接口上多种UNIX和Linux版本的开放端口。通过对本网站和其他网站的研究,我得到了类似以下代码:Java 在*NIX上检测打开的端口时出现问题,java,linux,sockets,unix,Java,Linux,Sockets,Unix,我正在尝试编写一个程序,该程序将检测系统上所有接口上多种UNIX和Linux版本的开放端口。通过对本网站和其他网站的研究,我得到了类似以下代码: try { SocketServer s = new SocketServer(port, 0, host).close(); } catch ( Exception ex ) { do something here... } 与此类似: DatagramSocket d = new DatagramSocket(port, host
try {
SocketServer s = new SocketServer(port, 0, host).close();
} catch ( Exception ex ) {
do something here...
}
与此类似:
DatagramSocket d = new DatagramSocket(port, host).close();
代码在RHEL6上运行得非常好。但是,在AIX 7、HP-UX 11.31和Solaris 10和11上,未检测到某些打开的端口。例如,代码没有报告SSH(TCP 22)打开,每个系统上都有一个SSH守护进程(这就是我连接到系统的方式)。但是SSH守护进程并不是唯一一个未报告的开放端口
我在一个线程中遇到一条评论,指出在Java 7及更高版本上使用SocketServer似乎效果不佳,并建议将代码转换为客户端套接字连接:
Socket s = new Socket(host, port);
此代码工作得更好,但速度要慢得多(因为在关闭/非活动端口上等待连接)。它也不是100%准确。(我可以理解这是一种程序声明了一个端口,但不接受该端口上的连接的情况。)
我应该注意,我使用netstat输出作为比较基础。例如,在Linux上:
# netstat --protocol=inet -aln
其他方面也类似:
# netstat -f inet -an
我希望使用Java的本机网络来解决这个问题,因为它应该可以跨所有目标平台工作。但我还没有找到一个在所有平台上都能100%工作的解决方案
所以,我的问题。以前是否有人经历过这种情况,并找到了一种跨多个平台工作的方法?如果是这样的话,你能告诉我它的方向吗
多谢各位
约翰
更新日期:2015年5月5日
发现了一些额外的信息(感谢一位同事发现了很多这方面的信息)
1) 我运行的所有系统(RHEL 6系统除外)都有双栈(IPv4和IPv6)。控制这一点的JVM网络属性是java.net.preferIPv4Stack属性。可以在找到的Oracle文档中找到解释
2) SO_REUSEADDR和SO_REUSEPORT套接字选项也可能涉及一些交互。上面有一个很好的StackOverflow线程
3) 最后,JDK中有一个bug已经解决了。这个bug只提到了Windows7和2008。我把它放在这里作为参考,以防有人无意中发现这条线索。链接是
j
新的SocketServer(端口,0,主机)
在这些调用中,您对host
使用了什么值?纯粹的推测:您可以评估端口扫描程序(如netmap)使用一些Java接口对“原始套接字”使用的技术(我刚刚在谷歌上搜索了“rocksaw Java”).Spring附带了一个类,该类具有查找可用套接字的方法:什么是SocketServer
?作为对@Kenster的响应,上面提到的代码在一个循环中运行,该循环测试服务器上的每个接口地址(包括localhost)。