Сетевые интерфейсы

Тема в разделе "Lotus + Java + LS2J", создана пользователем lmike, 3 ноя 2015.

  1. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    часто возникают вопросы по работе с сетью и сетевыми интерфейсами...
    для LS адаптировать не стал..., куски на java
    итераторы реализовал для 8-ой java (уж извиняйте), в коде оставил ссылки на оригиналы
    Код (Java):
    //https://docs.oracle.com/javase/tutorial/networking/nifs/listing.html
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import static java.lang.System.out;
     
    public class ListNets {
     
        public static void main(String args[]) throws SocketException {
            Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
            for (NetworkInterface netint : Collections.list(nets))
                displayInterfaceInformation(netint);
        }
     
        static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
            out.printf("Display name: %s\n", netint.getDisplayName());
            out.printf("Name: %s\n", netint.getName());
            Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
            for (InetAddress inetAddress : Collections.list(inetAddresses)) {
                out.printf("InetAddress: %s\n", inetAddress);
            }
            out.printf("\n");
         }
    }
    Код (Java):
    import org.apache.commons.net.util.SubnetUtils;
    import java.net.*;
    import java.util.*;
    import static java.lang.System.out;
    class SomeClass{
    ....
        public static <T> T[] concatAll(T[] first, T[]... rest) {
            //http://stackoverflow.com/questions/80476/how-can-i-concatenate-two-arrays-in-java
            int totalLength = first.length;
            for (T[] array : rest) {
                totalLength += array.length;
            }
            T[] result = Arrays.copyOf(first, totalLength);
            int offset = first.length;
            for (T[] array : rest) {
                System.arraycopy(array, 0, result, offset, array.length);
                offset += array.length;
            }
            return result;
        }
     
        public static String[] getRangeFromLocal(int ifNum) {
            String[] res = null;
            NetworkInterface liface;
            try {
                if (ifNum >= 0) {
                    liface = Collections.list(NetworkInterface.getNetworkInterfaces()).get(ifNum);
                    //displayInterfaceInformation(liface);
                    //res=new String[]{liface.getInterfaceAddresses().get(0).getAddress().getHostAddress()};
                    res = new SubnetUtils(liface.getInterfaceAddresses().get(0).getAddress().getHostAddress() + "/" + String.valueOf(liface.getInterfaceAddresses().get(0).getNetworkPrefixLength())).getInfo().getAllAddresses();
                } else {
                    res = Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
    //              networkInterface.getInterfaceAddresses().stream()
                            .filter(iface -> {
                                boolean ret = true;
                                try {
                                    ret = !iface.isLoopback();
                                } catch (SocketException e) {
                                    e.printStackTrace();
                                }
                                return ret;
                            })
                            .map(iface -> {
                                return new SubnetUtils(iface.getInterfaceAddresses().get(0).getAddress().getHostAddress() +
                                        "/" + String.valueOf(iface.getInterfaceAddresses().get(0).getNetworkPrefixLength())).getInfo().getAllAddresses();
                            })
                            .reduce(new String[]{}, (s1, s2) -> {
                                return concatAll(s1, s2);
                            });
                }
            } catch (SocketException e) {
                e.printStackTrace();
            }
            return res;
        }
    }
     
     
  2. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    докручено - получение списка сетей (именно списка, в виде массива строк с адресами) основываясь на адресах и масках их интерфейсов локального компа
    [DOUBLEPOST=1446557694,1446557489][/DOUBLEPOST]сканирование сетей (реально быстрое, т.к. в отдельном потоке и неблокирующее)
    Код (Java):
    package kodiForm;
    /*
    * @(#)Ping.java 1.2 01/12/13
    * Connect to each of a list of hosts and measure the time required to complete
    * the connection.  This example uses a selector and two additional threads in
    * order to demonstrate non-blocking connects and the multithreaded use of a
    * selector.
    *
    * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or
    * without modification, are permitted provided that the following
    * Redistribution and use in source and binary forms, with or
    * without modification, are permitted provided that the following
    * conditions are met:
    *
    * -Redistributions of source code must retain the above copyright
    *
    * -Redistributions of source code must retain the above copyright
    * notice, this  list of conditions and the following disclaimer.
    *
    * -Redistribution in binary form must reproduct the above copyright
    * notice, this list of conditions and the following disclaimer in
    * the documentation and/or other materials provided with the
    *
    * -Redistribution in binary form must reproduct the above copyright
    * notice, this list of conditions and the following disclaimer in
    * the documentation and/or other materials provided with the
    * distribution.
    *
    * Neither the name of Oracle nor the names of
    * contributors may be used to endorse or promote products derived
    *
    * Neither the name of Oracle nor the names of
    * contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * This software is provided "AS IS," without a warranty of any
    * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
    * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
    * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
    * DAMAGES OR LIABILITIES  SUFFERED BY LICENSEE AS A RESULT OF  OR
    * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
    * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
    * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
    * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
    * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
    * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
    *
    * This software is provided "AS IS," without a warranty of any
    * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
    * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
    * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
    * DAMAGES OR LIABILITIES  SUFFERED BY LICENSEE AS A RESULT OF  OR
    * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
    * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
    * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
    * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
    * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
    * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
    * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    *
    * You acknowledge that Software is not designed, licensed or
    * intended for use in the design, construction, operation or
    * maintenance of any nuclear facility.
    *
    * You acknowledge that Software is not designed, licensed or
    * intended for use in the design, construction, operation or
    * maintenance of any nuclear facility.
    */

     
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.regex.Pattern;
    import java.util.stream.Collectors;
     
     
    public class Ping {
     
        // The default daytime port
        static int DAYTIME_PORT = 13;
        // The default http port
        static int HTTP_PORT = 80;
        // the default ssh port
        static int SSH_PORT = 22;
        // The port we'll actually use
        static int port = SSH_PORT;
     
     
        // Representation of a ping target
        //
        //
        static class Target {
     
            private InetSocketAddress address;
            private SocketChannel channel;
            private Exception failure;
            private long connectStart;
            private long connectFinish = 0;
            private boolean shown = false;
            private boolean connected = false;
     
            Target(String host) {
                try {
                    address = new InetSocketAddress(InetAddress.getByName(host),
                            port);
                } catch (IOException x) {
                    failure = x;
                }
            }
     
            void show() {
                String result;
                if (connectFinish != 0)
                    result = Long.toString(connectFinish - connectStart) + "ms";
                else if (failure != null)
                    result = failure.toString();
                else
                    result = "Timed out";
                System.out.println(address + " : " + result);
                shown = true;
            }
     
            public InetSocketAddress getAddress() {
                InetSocketAddress res=null;
                if (connectFinish != 0) {
                    res = address;
                    connected = true;
                }
                return res;
            }
        }
     
        // Thread for printing targets as they're heard from
        //
        static class Printer
                extends Thread {
            LinkedList pending = new LinkedList();
     
            Printer() {
                setName("Printer");
                setDaemon(true);
            }
     
            void add(Target t) {
                synchronized (pending) {
                    pending.add(t);
                    pending.notify();
                }
            }
     
            public void run() {
                try {
                    for (; ; ) {
                        Target t = null;
                        synchronized (pending) {
                            while (pending.size() == 0)
                                pending.wait();
                            t = (Target) pending.removeFirst();
                        }
                        t.show();
                    }
                } catch (InterruptedException x) {
                    return;
                }
            }
     
        }
     
     
        // Thread for connecting to all targets in parallel via a single selector
        //
        //
        static class Connector
                extends Thread {
            Selector sel;
            Printer printer;
     
            // List of pending targets.  We use this list because if we try to
            // register a channel with the selector while the connector thread is
            // blocked in the selector then we will block.
            //
            LinkedList pending = new LinkedList();
     
            Connector(Printer pr) throws IOException, InterruptedException {
                printer = pr;
                sel = Selector.open();
                setName("Connector");
            }
     
            // Initiate a connection sequence to the given target and add the
            // target to the pending-target list
            //
            void add(Target t) {
                SocketChannel sc = null;
                try {
     
                    // Open the channel, set it to non-blocking, initiate connect
                    sc = SocketChannel.open();
                    sc.configureBlocking(false);
                    // Open the channel, set it to non-blocking, initiate connect
                    sc = SocketChannel.open();
                    sc.configureBlocking(false);
     
                    boolean connected = sc.connect(t.address);
     
                    // Record the time we started
                    t.channel = sc;
                    t.connectStart = System.currentTimeMillis();
     
                    if (connected) {
                        t.connectFinish = t.connectStart;
                        sc.close();
                        printer.add(t);
                    } else {
                        // Add the new channel to the pending list
                        synchronized (pending) {
                            pending.add(t);
                        }
     
                        // Nudge the selector so that it will process the pending list
                        sel.wakeup();
                    }
                } catch (IOException x) {
                    if (sc != null) {
                        try {
                            sc.close();
                        } catch (IOException xx) {
                        }
                    }
                    t.failure = x;
                    printer.add(t);
                }
            }
     
            // Process any targets in the pending list
            //
            void processPendingTargets() throws IOException {
                synchronized (pending) {
                    while (pending.size() > 0) {
                        Target t = (Target) pending.removeFirst();
                        try {
     
                            // Register the channel with the selector, indicating
                            // interest in connection completion and attaching the
                            // target object so that we can get the target back
                            // after the key is added to the selector's
                            // selected-key set
                            t.channel.register(sel, SelectionKey.OP_CONNECT, t);
                            // Register the channel with the selector, indicating
                            // interest in connection completion and attaching the
                            // target object so that we can get the target back
                            // after the key is added to the selector's
                            // selected-key set
                            t.channel.register(sel, SelectionKey.OP_CONNECT, t);
     
                        } catch (IOException x) {
     
                            // Something went wrong, so close the channel and
                            // record the failure
                            t.channel.close();
                            t.failure = x;
                            printer.add(t);
                            // Something went wrong, so close the channel and
                            // record the failure
                            t.channel.close();
                            t.failure = x;
                            printer.add(t);
     
                        }
                    }
     
                }
            }
     
            // Process keys that have become selected
            //
            void processSelectedKeys() throws IOException {
                for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) {
     
                    // Retrieve the next key and remove it from the set
                    SelectionKey sk = (SelectionKey) i.next();
                    i.remove();
     
                    // Retrieve the target and the channel
                    Target t = (Target) sk.attachment();
                    SocketChannel sc = (SocketChannel) sk.channel();
     
                    // Attempt to complete the connection sequence
                    try {
                        if (sc.finishConnect()) {
                            sk.cancel();
                            t.connectFinish = System.currentTimeMillis();
                            sc.close();
                            printer.add(t);
                        }
                    } catch (IOException x) {
                        sc.close();
                        t.failure = x;
                        printer.add(t);
                    }
                }
            }
     
     
            volatile boolean shutdown = false;
     
            // Invoked by the main thread when it's time to shut down
            //
            void shutdown() {
                shutdown = true;
                sel.wakeup();
            }
     
            // Connector loop
            //
            public void run() {
                for (; ; ) {
                    try {
                        int n = sel.select();
                        if (n > 0)
                            processSelectedKeys();
                        processPendingTargets();
                        if (shutdown) {
                            sel.close();
                            return;
                        }
                    } catch (IOException x) {
                        x.printStackTrace();
                    }
                }
            }
     
        }
     
     
        public static void main(String[] args)
                throws InterruptedException, IOException {
            if (args.length < 1) {
                System.err.println("Usage: java Ping [port] host...");
                return;
            }
            int firstArg = 0;
     
            // If the first argument is a string of digits then we take that
            // to be the port number to use
            if (Pattern.matches("[0-9]+", args[0])) {
                port = Integer.parseInt(args[0]);
                firstArg = 1;
            }
     
            // Create the threads and start them up
            Printer printer = new Printer();
            printer.start();
            Connector connector = new Connector(printer);
            connector.start();
     
            // Create the targets and add them to the connector
            LinkedList<Target> targets = new LinkedList();
    /*      for (int i = firstArg; i < args.length; i++) {
            Target t = new Target(args[i]);
            targets.add(t);
            connector.add(t);
        }
    */

            Arrays.asList(NetUtils.getRangeFromLocal(3)).forEach(saddr -> {
                Target t = new Target(saddr);
                targets.add(t);
                connector.add(t);
            });
            // Wait for everything to finish
            Thread.sleep(500);
            connector.shutdown();
            connector.join();
            List<Target> filtered= targets.stream()
                    .filter(t -> t.getAddress() != null)
                    .collect(Collectors.toList());
                    //.forEach(t -> System.out.println(t.address.toString()));
            System.out.println("*************");
                    filtered.forEach(t -> System.out.println(t.address.toString()));
     
            // Print status of targets that have not yet been shown
    /*      for (Iterator i = targets.iterator(); i.hasNext(); ) {
                Target t = (Target) i.next();
                if (!t.shown)
                    t.show();
            }
    */

        }
     
    }
     
    https://docs.oracle.com/javase/7/docs/technotes/guides/io/example/Ping.java
    дополнил (чутка) получением откликнувшихся хостов, порт использовал 22 (там по коду - сверху). Код на сайте поломатый - я его поправил
    в коде заюзан метод из предыдущего поста (NetUtils.getRangeFromLocal(3))
     
    #2 lmike, 3 ноя 2015
    Последнее редактирование модератором: 3 ноя 2015
  3. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    список хостов подсети я получал под свои нужды (сканирования), в апачевсой либе есть просто проверка на принадлежность хоста подсети
    еще есть UPnP с cling - не вижу смысла выкладывать, просто FYI для методов сканирования
     
  4. garrick

    garrick Lotus team
    Lotus team

    Регистрация:
    26 окт 2009
    Сообщения:
    773
    Симпатии:
    52
    Если я всё правильно понял, то For-Each Loop были уже в 5-й Java. Т.о. в 8-ом Лотусе должно работать.
     
  5. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    разумеется, но синтаксис для лямбд меня прельщает больше ;), а вот они "не будут работать"
     
  6. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    внес коррекции
    код с сайта - жрал сокеты, сделал их убиение в finally, вынес фильтры для сетей, добавил фильтры для IPV4 и ввел ограничение маски сетей (до /20):
    Код (Java):
    package kodiForm;
     
    import org.apache.commons.net.util.SubnetUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    import java.io.IOException;
    import java.net.*;
    import java.util.*;
    import java.util.function.Predicate;
    import java.util.regex.Pattern;
    import java.util.stream.Collectors;
     
    import static java.lang.System.out;
    /**
     * Created by mike on 29.10.15.
     */

    public class NetUtils {
        private static int TIMEOUT=500;
        private static short MASQ_LIIM=20;//limit prefix masq len for restrict lage network scan
        private static final String resPath="./res";
            private static final Logger LOG=LoggerFactory.getLogger(new Throwable() .getStackTrace()[0].getClassName());;
        private static Predicate<NetworkInterface> notLoopback=iface -> {
            boolean ret=false;
            try {
                ret = !iface.isLoopback();
            } catch (SocketException e) {
                e.printStackTrace();
            }
            return ret;};
        private static Predicate<NetworkInterface> notFake=iface -> {
            boolean ret=false;
            try {
                ret = !iface.isLoopback() & !iface.isPointToPoint()
                        & (Collections.list(iface.getInetAddresses()).size()>0)
                        & !iface.isVirtual();
            } catch (SocketException e) {
                e.printStackTrace();
            }
            return ret;};
        private static Predicate<InterfaceAddress> masq=addr -> {
            boolean ret=false;
            ret = addr.getNetworkPrefixLength()>=MASQ_LIIM;
            return ret;};
        private static Predicate<InterfaceAddress> ipv4=addr -> {
            LOG.info("filter IPV4 for:" +addr.getAddress().getHostAddress());
            return addr.getAddress() instanceof Inet4Address;
        };
     
        //http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/util/SubnetUtils.html
        //http://stackoverflow.com/questions/2942299/converting-cidr-address-to-subnet-mask-and-network-address
     
        /**
         *
         * @param address tested address
         * @param subnet CIDR notation
         * @return true if included
         */

        public static boolean checkIpBySubNet(String address, String subnet){
            SubnetUtils utils = new SubnetUtils(subnet);
            return utils.getInfo().isInRange(address);
        }
     
        /**
         *
         * @param address tested address
         * @param subnetaddr address from subnet (any known)
         * @param mask mask
         * @return true if included
         */

        public static boolean checkIpBySubNet(String address, String subnetaddr, String mask){
            SubnetUtils utils = new SubnetUtils(subnetaddr, mask);
            return utils.getInfo().isInRange(address);
        }
        public static List<String> accessibleRange(String anyIp) {
            ArrayList<String> res=new ArrayList<String>();
            InetAddress[] addrs=null;
            try {
                 addrs= InetAddress.getAllByName(anyIp);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            for(InetAddress addr: addrs){
                try {
                    if (addr.isReachable(1000)){res.add(addr.getHostAddress());}
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return res;
        }
     
        public static List<String> accessibleRange() {
            ArrayList<String> res=new ArrayList<String>();
            for(String saddr: getRangeFromLocal(0)) {
                InetAddress addr = null;
                try {
                    addr = InetAddress.getByName(saddr);
                    if (addr.isReachable(TIMEOUT)) {
                        res.add(addr.getHostAddress());
                    } else {
                        System.out.println("Is Not reachiable: " + addr.getHostAddress());
                    }
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return res;
        }
        public static <T> T[] concatAll(T[] first, T[]... rest) {
            //http://stackoverflow.com/questions/80476/how-can-i-concatenate-two-arrays-in-java
            int totalLength = first.length;
            for (T[] array : rest) {
                totalLength += array.length;
            }
            T[] result = Arrays.copyOf(first, totalLength);
            int offset = first.length;
            for (T[] array : rest) {
                System.arraycopy(array, 0, result, offset, array.length);
                offset += array.length;
            }
            return result;
        }
     
        public static List<NetworkInterface> getIfaces() throws SocketException {
            return Collections.list(NetworkInterface.getNetworkInterfaces()).stream().filter(notFake).collect(Collectors.toList());
        }
     
        public static String[] getRangeFromLocal(int ifNum) {
            String[] res = {};
            NetworkInterface liface;
            try {
                if (ifNum >= 0) {
                    //liface = Collections.list(NetworkInterface.getNetworkInterfaces()).get(ifNum);
                    //liface=NetworkInterface.getByIndex(ifNum); // by real num in interfaces list
                    liface=getIfaces().get(ifNum);
                    //displayInterfaceInformation(liface);
                    //res=new String[]{liface.getInterfaceAddresses().get(0).getAddress().getHostAddress()};
                    //filter only IPV4
                    res=liface.getInterfaceAddresses().stream()
                            .filter(ipv4)
                            .filter(masq)
                            .map(a->{return new SubnetUtils(a.getAddress().getHostAddress() + "/" + String.valueOf(a.getNetworkPrefixLength())).getInfo().getAllAddresses();})
                            .reduce(new String[] {}, (s1,s2)->{return concatAll(s1, s2);});
                    /*for(InterfaceAddress addr:liface.getInterfaceAddresses()){
                        LOG.info(addr.getAddress().getHostAddress() + "/" +addr.getNetworkPrefixLength());
                        res = concatAll(res,new SubnetUtils(addr.getAddress().getHostAddress() + "/" + String.valueOf(addr.getNetworkPrefixLength())).getInfo().getAllAddresses());
                    }*/

    //            res = new SubnetUtils(liface.getInterfaceAddresses().get(0).getAddress().getHostAddress() + "/" + String.valueOf(liface.getInterfaceAddresses().get(0).getNetworkPrefixLength())).getInfo().getAllAddresses();
                } else {
                    res = Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
    //              networkInterface.getInterfaceAddresses().stream()
                            .filter(notFake)
                            //for each interface (excluding localhost, virtual, P2P)
                            //return String[]
                            .map(iface -> {
                                return iface.getInterfaceAddresses().stream()
                                        .filter(ipv4)
                                        .filter(masq)
                                        //for each ipv4 address on interface
                                        .map(a->{return new SubnetUtils(a.getAddress().getHostAddress() + "/" + String.valueOf(a.getNetworkPrefixLength())).getInfo().getAllAddresses();})
                                        .reduce(new String[] {}, (s1,s2)->{return concatAll(s1, s2);});
    //                          return new SubnetUtils(iface.getInterfaceAddresses().get(0).getAddress().getHostAddress() +
    //                                  "/" + String.valueOf(iface.getInterfaceAddresses().get(0).getNetworkPrefixLength())).getInfo().getAllAddresses();
                            })
                            //return combined String[] (for all interfaces)
                            .reduce(new String[]{}, (s1, s2) -> {
                                return concatAll(s1, s2);
                            });
                }
            } catch (SocketException e) {
                e.printStackTrace();
            }
            return res;
        }
     
        static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
            //https://docs.oracle.com/javase/tutorial/networking/nifs/listing.html
            out.printf("Display name: %s\n", netint.getDisplayName());
            out.printf("Name: %s\n", netint.getName());
            out.printf("Index: %s\n",netint.getIndex());
            Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
            for (InetAddress inetAddress : Collections.list(inetAddresses)) {
                out.printf("InetAddress: %s\n", inetAddress);
            }
            out.printf("\n");
        }
     
        public static void main(String args[]){
            //createFtpUser("test","fortestonly");
            //startFtp("1680");
            //accessibleRange().forEach(addr->System.out.println(addr));
            Enumeration<NetworkInterface> nets = null;
            try {
                nets = NetworkInterface.getNetworkInterfaces();
                for (NetworkInterface netint : Collections.list(nets))
                    if (!netint.isLoopback() & !netint.isPointToPoint()
                            & (Collections.list(netint.getInetAddresses()).size()>0)
                            & !netint.isVirtual())displayInterfaceInformation(netint);
            } catch (SocketException e) {
                e.printStackTrace();
            }
            if (args.length < 1) {
                System.err.println("Usage: java Ping ifaceNum");
                return;
            }
            int firstArg =-1;
            if (Pattern.matches("[0-9]+", args[0])) {
                firstArg = Integer.parseInt(args[0]);
            }
    //firstArg=-1;
            out.printf("Param: %d\n", firstArg);
            out.println(Arrays.toString(getRangeFromLocal(firstArg)));
            //return 0;
        }
     
    }
     
    Код (Java):
    package kodiForm;
    /*
     * @(#)Ping.java 1.2 01/12/13
     * Connect to each of a list of hosts and measure the time required to complete
     * the connection.  This example uses a selector and two additional threads in
     * order to demonstrate non-blocking connects and the multithreaded use of a
     * selector.
     *
     * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
     *
     * отстальная часть отмазок, в посте выше
     */

     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    import java.io.IOException;
    import java.io.InterruptedIOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.util.*;
    import java.util.regex.Pattern;
    import java.util.stream.Collectors;
     
    public class Ping {
        private static final Logger LOG= LoggerFactory.getLogger(new Throwable() .getStackTrace()[0].getClassName());
        // The default daytime port
        static int DAYTIME_PORT = 13;
        // The default http port
        static int HTTP_PORT = 80;
        // the default ssh port
        static int SSH_PORT = 22;
        // The port we'll actually use
        static int port = SSH_PORT;
        static short TIMEOUT_SELECT=10;//10ms timeout for nio select
        static boolean logConnect=true;
     
        static final Broker broker=new Broker();
     
        static void add2broker(Object o){
            broker.add(o);
            logConnect=false;
        }
     
        // Representation of a ping target
        //
        //
        class Target {
     
            private InetSocketAddress address;
            private SocketChannel channel;
            private Exception failure;
            private long connectStart;
            private long connectFinish = 0;
            private boolean shown = false;
            private boolean connected = false;
     
            Target(String host) {
                try {
                    address = new InetSocketAddress(InetAddress.getByName(host),
                            port);
                } catch (IOException x) {
                    failure = x;
                }
            }
     
            void show() throws IOException {
                String result;
                if (connectFinish != 0) {
                    result = Long.toString(connectFinish - connectStart) + "ms";
                    broker.publish(address.getAddress().getHostAddress());
                }else if (failure != null)
                    result = failure.toString();
                else
                    result = "Timed out";
                //channel.close();
                //System.out.println(address + " : " + result);
                if (logConnect) LOG.info((address + " : " + result));
                shown = true;
            }
     
            public InetSocketAddress getAddress() {
                InetSocketAddress res=null;
                if (connectFinish != 0) {
                    res = address;
                    connected = true;
                }
                return res;
            }
        }
     
        // Thread for printing targets as they're heard from
        //
        static class Printer
                extends Thread {
            LinkedList pending = new LinkedList();
     
            Printer() {
                setName("Printer");
                setDaemon(true);
            }
     
            void add(Target t) {
                synchronized (pending) {
                    pending.add(t);
                    pending.notify();
                }
            }
     
            public void run() {
                try {
                    for (; ; ) {
                        Target t = null;
                        synchronized (pending) {
                            while (pending.size() == 0)
                                pending.wait();
                            t = (Target) pending.removeFirst();
                        }
                            t.show();
                    }
                } catch (InterruptedException | IOException x) {
                    return;
                }
            }
     
        }
     
     
        // Thread for connecting to all targets in parallel via a single selector
        //
        //
        class Connector
                extends Thread {
            Selector sel;
            Printer printer;
     
            // List of pending targets.  We use this list because if we try to
            // register a channel with the selector while the connector thread is
            // blocked in the selector then we will block.
            //
            LinkedList pending = new LinkedList();
     
            Connector(Printer pr) throws IOException, InterruptedException{
                printer = pr;
                sel = Selector.open();
                setName("Connector");
            }
     
            // Initiate a connection sequence to the given target and add the
            // target to the pending-target list
            //
            void add(Target t) {
                SocketChannel sc = null;
                try {
     
                    // Open the channel, set it to non-blocking, initiate connect
                    sc = SocketChannel.open();
                    sc.configureBlocking(false);
    /* <p> If this channel is in non-blocking mode then an invocation of this
    * method initiates a non-blocking connection operation.  If the connection
    * is established immediately, as can happen with a local connection, then
    * this method returns <tt>true</tt>.  Otherwise this method returns
    * <tt>false</tt> and the connection operation must later be completed by
    * invoking the {@link #finishConnect finishConnect} method.
    */

                    boolean connected = sc.connect(t.address);
     
                    // Record the time we started
                    t.channel = sc;
                    t.connectStart = System.currentTimeMillis();
     
                    if (connected) {
                        t.connectFinish = t.connectStart;
                        sc.close();
                        printer.add(t);
                    } else {
                        // Add the new channel to the pending list
                        synchronized (pending) {
                            pending.add(t);
                        }
     
                        // Nudge the selector so that it will process the pending list
                        sel.wakeup();
                    }
                } catch (IOException x) {
                    if (sc != null) {
                        try {
                            sc.close();
                        } catch (IOException xx) {
                        }
                    }
                    t.failure = x;
                    printer.add(t);
                }
            }
     
            // Process any targets in the pending list
            //
            void processPendingTargets() throws IOException {
                synchronized (pending) {
                    while (pending.size() > 0) {
                        Target t = (Target) pending.removeFirst();
                        try {
     
                            // Register the channel with the selector, indicating
                            // interest in connection completion and attaching the
                            // target object so that we can get the target back
                            // after the key is added to the selector's
                            // selected-key set
                            t.channel.register(sel, SelectionKey.OP_CONNECT, t);
     
                        } catch (IOException x) {
                            // Something went wrong, so close the channel and
                            // record the failure
                            t.channel.close();
                            t.failure = x;
                            printer.add(t);
                        }
                    }
     
                }
            }
     
            // Process keys that have become selected
            //
            void processSelectedKeys() throws IOException {
    /*
                for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) {
     
                    // Retrieve the next key and remove it from the set
                    SelectionKey sk = (SelectionKey) i.next();
                    i.remove();
     
                    // Retrieve the target and the channel
                    Target t = (Target) sk.attachment();
                    SocketChannel sc = (SocketChannel) sk.channel();
     
                    // Attempt to complete the connection sequence
                    try {
                        if (sc.finishConnect()) {
                            sk.cancel();
                            t.connectFinish = System.currentTimeMillis();
                            sc.close();
                            printer.add(t);
                        }
                    } catch (IOException x) {
                        sc.close();
                        t.failure = x;
                        printer.add(t);
                    }
                }
    */

                //http://tutorials.jenkov.com/java-nio/selectors.html
                Set<SelectionKey> selectedKeys = sel.selectedKeys();
     
                Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
     
                while(keyIterator.hasNext()) {
     
                    SelectionKey key = keyIterator.next();
                    keyIterator.remove();
     
                    if(key.isAcceptable()) {
                        // a connection was accepted by a ServerSocketChannel.
     
                    } else if (key.isConnectable()) {
                        // a connection was established with a remote server.
                        Target t = (Target) key.attachment();
                        SocketChannel sc = (SocketChannel) key.channel();
                        try {//test connection for reject
                            if (sc.finishConnect()) {
                                key.cancel();
                                t.connectFinish = System.currentTimeMillis();
                                sc.close();
                                printer.add(t);
                            }
                        } catch (IOException x) {
                            sc.close();
                            t.failure = x;
                            printer.add(t);
                        }
     
                    } else if (key.isReadable()) {
                        // a channel is ready for reading
     
                    } else if (key.isWritable()) {
                        // a channel is ready for writing
                    }
     
                }
            }
     
     
            volatile boolean shutdown = false;
     
            // Invoked by the main thread when it's time to shut down
            //
            void shutdown() {
                shutdown = true;
                sel.wakeup();
            }
     
            // Connector loop
            //
            public void run() {
                for (; ; ) {
                    try {
                        int n = sel.select(TIMEOUT_SELECT);
                        if (n > 0)
                            processSelectedKeys();
                        processPendingTargets();
                        if (shutdown) {
                            sel.close();
                            //sel=null;
                            return;
                        }
                    } catch (InterruptedIOException e){
                        try {
                            sel.close();
                        } catch (IOException e1) {
                            LOG.error("failed within Interruption!",e1);
                            //e1.printStackTrace();
                        }
                        return;
                    } catch (IOException x) {
                        LOG.error("failed!",x);
                        //x.printStackTrace();
                    }
                }
            }
     
        }
        public List<Target>  pingIface(int iface, long timeout) throws IOException, InterruptedException {
            Printer printer = new Printer();
            printer.start();
            Connector connector = new Connector(printer);
            connector.start();
            List<Target> filtered=null;
            LinkedList<Target> targets = new LinkedList();
            try {
     
            // Create the targets and add them to the connector
    /*      for (int i = firstArg; i < args.length; i++) {
            Target t = new Target(args[i]);
            targets.add(t);
            connector.add(t);
        }
    */

                //final Connector finalConnector = connector;
                Arrays.stream(NetUtils.getRangeFromLocal(iface)).forEach(saddr -> {
                    Target t = new Target(saddr);
                    targets.add(t);
                    connector.add(t);
                });
                // Wait for everything to finish
                if (timeout>0) Thread.sleep(timeout);
     
                filtered = targets.stream()
                        .filter(t -> t.getAddress()!= null)
                        .collect(Collectors.toList());
     
                if (logConnect) {
                //.forEach(t -> System.out.println(t.address.toString()));
                    LOG.info("*************");
                    filtered.forEach(t -> LOG.info(String.valueOf(t.address)));
                }
                //System.out.println(""+filtered.parallelStream().map(t ->String.valueOf(t.address)).collect(Collectors.toList()));
    /*
                connector.shutdown();
                connector.join();
                printer.interrupt();
    */

            } finally {
                connector.shutdown();
                connector.interrupt();
                printer.interrupt();
                //clear all opened Sockets
                targets.forEach(t -> {
                    try {
                        if (t.channel!=null && t.channel.isOpen()){
                            if (logConnect)LOG.info("*channel Address: "+String.valueOf(t.channel.getRemoteAddress()));
                            t.channel.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                LOG.info("************* Finally exit");
            }
            // Print status of targets that have not yet been shown
    /*      for (Iterator i = targets.iterator(); i.hasNext(); ) {
                Target t = (Target) i.next();
                if (!t.shown)
                    t.show();
            }
    */

            return filtered;
        }
     
        public static void main(String[] args)
                throws InterruptedException, IOException {
    /*
            if (args.length < 1) {
                System.err.println("Usage: java Ping [port] host...");
                return;
            }
            int firstArg = 0;
     
            // If the first argument is a string of digits then we take that
            // to be the port number to use
            if (Pattern.matches("[0-9]+", args[0])) {
                port = Integer.parseInt(args[0]);
                firstArg = 1;
            }
    */

     
            if (args.length < 1) {
                System.err.println("Usage: java Ping ifaceNum");
                return;
            }
            class My extends Component{
                @Subscription
                public void onString(String s) {
                    LOG.info("My String: "+s);
                    //System.out.println("String - " + s);
                }
     
            }
            //add2broker(new My());
            int firstArg = -1;
            if (Pattern.matches("[0-9]+", args[0])) {
                firstArg = Integer.parseInt(args[0]);
            }
            Ping ping=new Ping();
            ping.pingIface(firstArg, 500);
        }
     
    }
     
     
  7. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    кому интересно читать про nio - сюда
    в чем смысл - одна треда открывает кучу сокетов параллельно!
    кол-во сокетов - зависит от подсети для каждого интерфейса
    по умолчанию - боянит по всем сетевым интерфейсам, кот. есть IPV4 и кот. проходят по маске (ну и остальные фильтры)
    время сканирования очень мало - отклик от всех рабочих адресов, в локалке, получается менее 500мс
    влияние
    Код (Java):
    int select(long timeout)
    в 10мс не обнаружил
    понятно что проверка открытия сокета - это не полная доступность сервиса, но существенно сократит диапазон проверки
    Важно! если в локалке есть IDS - могут быть вопросы ;)
    [DOUBLEPOST=1448284673,1448284596][/DOUBLEPOST]код брокера, в данном контексте, не так важен - потому не выложил
     
  8. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
Загрузка...
Похожие Темы - Сетевые интерфейсы
  1. Надя1972
    Ответов:
    2
    Просмотров:
    1.098
  2. malor
    Ответов:
    0
    Просмотров:
    3.093

Поделиться этой страницей