如何用java编写程序实现发现某一网段内的活动主机
解决方案 »
- 有什么好的软件可以打包jre和jar吗,希望打包后比较小,这样java转成课执行文件比较好弄
- 请帮我看一下哪里错了。谢谢。
- j2ee sdk是干什么用的? 和weblgic的功能有什么不同,j2ee sdk 是不是包含j2se sdk的功能?
- 暴急!!ResultSet的问题
- DOS下运行javac 出现乱码 还有声音,在线等
- java连接 oracle8
- 何为“多线程”
- session.putValue的问题,在线等待!!
- 高分求救:如何将嵌在JTabbedPane上的JTable (在JInternalFrame上)能冲满整个Panel?代码如下:
- package的问题,真正关键的问题
- 关于正则表达式的问题
- 菜鸟的一个小问题
String host = "192.168.1.181"
int timeOut = 3000;
boolean status = InetAddress.getByName(host).isReachable(timeOut);
InetAddress.isReachable()方法实现了ICMP,也就是Ping.(需要有一定的系统权限)
{
StringBuffer buf = new StringBuffer();
String s = "";
Process process;
try
{
process = Runtime.getRuntime().exec( "cmd /c " + "ping 127.0.0.1" );
BufferedReader br = new BufferedReader( new InputStreamReader(
process.getInputStream() ) );
while ( ( s = br.readLine() ) != null )
{
buf.append( s + "\r\n" );
} process.waitFor();
System.out.println( buf );
} catch ( Exception ex )
{
ex.printStackTrace();
}
}
为什么说有偏差呢?是因为:在isReachable(timeOut);的代码实现中--目前其实在WINDOWS平台,并没有采用ICMP协议来完成,而是采用TCP的PORT 7来完成功能的。因而不是通常从们所讲的PING的程序。
请看以下一段的说明:isReachable(timeOut);
方法最终调用的是native c的实现代码中的Inet4AddressImpl_isReachable0(...)
在该c的实现代码中有如下的一段话:
/*
* Windows implementation of ICMP & RAW sockets is too unreliable for now.
* Therefore it's best not to try it at all and rely only on TCP
* We may revisit and enable this code in the future.
*/
/*
* Can't create a raw socket, so let's try a TCP socket */
fd = NET_Socket(AF_INET, SOCK_STREAM, 0);
if (fd == JVM_IO_ERR) {
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew(env, WSAGetLastError(), "Can't create socket");
return JNI_FALSE;
}
if (ttl > 0) {
setsockopt(fd, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(ttl));
}
/*
* A network interface was specified, so let's bind to it.
*/
if (netif != NULL) {
if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "Can't bind socket");
closesocket(fd);
return JNI_FALSE;
}
} /*
* Make the socket non blocking so we can use select/poll.
*/
hEvent = WSACreateEvent();
WSAEventSelect(fd, hEvent, FD_READ|FD_CONNECT|FD_CLOSE); /* no need to use NET_Connect as non-blocking */
him.sin_port = htons(7); /* Echo */ connect_rv = connect(fd, (struct sockaddr *)&him, len); /**
* connection established or refused immediately, either way it means
* we were able to reach the host!
*/请看上边红色的部分,说明了native c的实现代码中其实是通过TCP向远方的PORT 7(即:ECHO服务)来达到“是否可达到”的功能的。目前并不是ICMP的实现。结论:
当然还是按SUN公司的JAVA 文档中的权威例子,即8楼火龙果所给的连接中的例子(Ping.java)。
感谢jiangnaisong的严谨态度,学习了。 看来官方API文档还不够全面,也不能完全相信。
import java.io.*;public class Ping
{
public static void main(String args[])
{
String line = null;
try
{
Process pro = Runtime.getRuntime().exec("ping 127.0.0.1 ");
BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));
while ((line = buf.readLine()) != null)
System.out.println(line);
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
}
}}
我看了一下这个官方的NIO ping的例子,并对其进行了调试和数据捕获。实际,这个官方的例子使用的方法并不是通过ICMP实现的,而是通过连接daytime端口13: // The default daytime port
static int DAYTIME_PORT = 13; // The port we'll actually use
static int port = DAYTIME_PORT;
try {
address = new InetSocketAddress(InetAddress.getByName(host),port);
} catch (IOException x) {
failure = x;
}
我也在Linux下使用了InetAddress.isReachable()方法做了试验:当使用普通用户时,使用的是连接echo端口7,使用root用户时,使用的是ICMP请求。通过对一台网络上的路由进行连接,两个测试结果都反回了true.InetAddress.isReachable()通过试图连接TCP端口的方法是利用了TCP/IP协议的三次握手原理,即使对方机器在端口上没有服务,当接收到请求时会立刻拒绝,如果对方机器不在网络上则结果是超时!这个方法的实现正是利用了这一点。总结:在使用java 1.5以上平台时,做用InetAddress.isReachable()方法是最佳的,推荐使用。
大家考虑酌情使用!