局域网跨网段根据主机名找IP

阅读更多

    本例需要被找的机器同时也在运行以下代码。目前是遍历所有IP进行查找,效率很低,在没找到更好的办法之前只好用它了。

/**
 * 在局域网(LAN)里面根据主机名找到对应的IP。
 * 设计作者: teasp
 * 信息描述:
 */
public class IpHostInLan
{
    private static final int PORT = 4321;
    private static final String NOT_FOUND = "NotFound";
    
    private ConcurrentHashMap map = new ConcurrentHashMap();
    
    private static IpHostInLan instance = new IpHostInLan();
    
    private volatile String resultIp = null;
    
    private IpHostInLan() 
    {
        new Thread() 
        {
            public void run()
            {
                try
                {
                    String localHost = InetAddress.getLocalHost().getHostName();
                    ServerSocket ss = new ServerSocket(PORT);
                    System.out.println("--------Listening to " + PORT + "----------");
                    while (true)
                    {
                        Socket socket = ss.accept();
                        try
                        {
                            
                            socket.getOutputStream().write(localHost.getBytes());
                            socket.getOutputStream().flush();
                            socket.close();
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                        finally 
                        {
                            if (socket != null) socket.close();
                        }
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }.start();
    }
    
    public static IpHostInLan instance()
    {
        return instance;
    }
    
    /**
     * 获取主机名对应的IP。如果map中没有那么到局域网里面去找。
     * @param host
     * @return
     */
    public  String getIp(String host)
    {
        String ip = map.get(host);
        
        if (ip != null)
        {
            //之前找过,现在不找了
            if (ip.equals(NOT_FOUND)) return null;
            
            return ip;
        }
        
        ip = search(host);
        if (ip == null)
        {
            map.put(host, NOT_FOUND);
        }
        else
        {
            map.put(host, ip);
        }
        
        return ip;
    }
    
    /**
     * 先在同一网段找,如果找不到再到其它网段找。
     * @param host
     * @return
     */
    private String search(String host)
    {
        String ip = null;
        try
        {
            ip = InetAddress.getByName(host).getHostAddress();
        }
        catch (Exception e)
        {
            System.out.println("failed to find " + host + " in my own IP segment.");
//            e.printStackTrace();
        }
        
        if (ip == null)
        {
            try
            {
                String[] segs = InetAddress.getLocalHost().getHostAddress().split("[.]");
                String prefix = segs[0] + "." + segs[1] + ".";
                int localSeg = Integer.valueOf(segs[2]);
                int i = 1;
                while (localSeg + i < 256 || localSeg - i > -1)
                {
                    if (localSeg + i < 256)
                    {
                        ip = search(host, prefix + (localSeg + i) + ".");
                        if (ip != null) break;
                    }
                    if (localSeg - i > -1)
                    {
                        ip = search(host, prefix + (localSeg - i) + ".");
                        if (ip != null) break;
                    }
                    i++;
                }
            }
            catch (UnknownHostException e)
            {
                e.printStackTrace();
            }
            
            System.out.format("Result from searching %s in other IP segments : %s\n", host, ip);
        }
        
        return ip;
    }

    /**
     * 同时只能做一个搜索。
     * @param host
     * @param prefix
     * @return
     */
    private synchronized String search(final String host, String prefix)
    {
        resultIp = null;
        
        System.out.format("Searching in %s segment...\n", prefix);
        
        ExecutorService service = Executors.newFixedThreadPool(64);
        
        for (int i=2; i<256; i++)
        {
            if (resultIp != null)
            {
                service.shutdownNow();
                break;
            }

            final String ip = prefix + i;
            service.submit(new Callable()
            {
                public String call()
                {
                    Socket socket = null;
                    try
                    {
                        socket = new Socket();
                        socket.connect(new InetSocketAddress(ip, PORT), 50);
                        InputStream in = socket.getInputStream();
                        BufferedReader br = new BufferedReader(new InputStreamReader(in));
                        String theHost = br.readLine();
                        if (host.equals(theHost))
                        {
                            resultIp = ip;
                            return ip;
                        }
                    }
                    catch (Exception e)
                    {
//                        e.printStackTrace();
                    }
                    finally
                    {
                        if (socket != null)
                            try
                            {
                                socket.close();
                            }
                            catch (IOException e)
                            {
                                e.printStackTrace();
                            }
                    }

                    return null;
                }
            });

        }
        
        service.shutdown();
        while (resultIp == null && false == service.isTerminated())
        {
            try
            {
                Thread.sleep(10);
            }
            catch (InterruptedException e)
            {
            }
        }
        service.shutdownNow();
        
        return resultIp;
    }
    
    public static void main(String[] args) throws IOException
    {
        System.out.println(IpHostInLan.instance().getIp(args[0]));
    }
}

 

你可能感兴趣的:(局域网,跨网段,主机名,计算机名,IP)