Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/32: Рейтинг темы: голосов - 32, средняя оценка - 4.72
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18

Не выполняется exec() сложной команды

14.07.2012, 08:56. Показов 6198. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача состоит в том, чтобы посредством Runtime.getRuntime().exec() получить результат выполнения команды консоли в Windows:
Bash
1
arp -a | findstr -C:"172.18.9.2 "
Будем считать что запись в ARP таблице существует - тоесть выполнение команды должно вернуть одну строчку соответствия IP и MAC адреса вида
Bash
1
172.18.9.2            00-06-28-71-5d-80     динамический
Выполняю на Java так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
String ip = "172.18.9.2";
String cmd = "arp -a | findstr " + ip;
Process pCat = Runtime.getRuntime().exec(cmd);
InputStream inCmd = pCat.getInputStream();
InputStream errCmd = pCat.getErrorStream();
BufferedReader outReader = new BufferedReader(new InputStreamReader(inCmd, "Cp866"));
String line;
while ((line = outReader.readLine ()) != null) { //считываем поток выхода
    System.out.println (line);
    }
outReader.close();
BufferedReader errReader = new BufferedReader(new InputStreamReader(errCmd, "Cp866"));
while ((line = errReader.readLine ()) != null) { //считываем поток ошибок
    System.out.println ("[Stderr] " + line);
    }
errReader.close();
inCmd.close();
errCmd.close();
При выполнении в NetBeans IDE 7.1.1 получаю

[Stderr] ARP: неверный параметр: |

если изменить строчку
Java
1
String cmd = "arp -a | findstr " + ip;
на
Java
1
String cmd[] = {"arp", "-a", " |", "findstr ", ip};
то получаю

[Stderr] ARP: неверный параметр: findstr

Со строчкой
Java
1
String cmd[] = {"arp", "-a"};
нормально выдает всю таблицу ARP.

Хотелось бы всетаки добиться выполнения сложной команды в Java, ибо в PHP эта команда выполняется замечательно.

Добавлено через 1 час 0 минут
задача решена упрощением консольной команды до
Bash
1
arp -a 172.18.9.2
тему можно закрывать, но всетаки как показала практика - сложные команды exec() не выполняет. а жаль.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.07.2012, 08:56
Ответы с готовыми решениями:

не выполняется exec('make') через ssh2
Доброго времени суток, у меня следующая проблема, я подключаюсь с одного сервера к другому через ssh средствами php (script1.php) и...

Передача аргумента в функцию,которая выполняется exec
Необходимо считать значение с текстового поля вроде f(x)="x+5","x-3" и т.д и посчитать значения функции f не понимаю почему не работает...

И снова о php exec() - выполняются не все команды
Проблема такая - работают обычные команды вроде ls или groups но например exec("/usr/bin/aplay /var/www/html/test.wav", $ret, $err) не...

14
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 12:39
Цитата Сообщение от Шуршик Посмотреть сообщение
как показала практика - сложные команды exec() не выполняет. а жаль.
вы наверное не понимаете значения пайпа (|), это не "сложная" команда, это перенаправления стандартного вывода одной команды на стандартный ввод другой, каким образом это относится к exec ? он пытается забирать вывод команды на InputStream а вы его перенаправили в пайпе на findstr и после этого утверждаете что он не умеет выполнять.
правильнее сказать что вы не понимаете что происходит и пользуетесь инструментом с обратной стороны
0
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18
14.07.2012, 14:12  [ТС]
сложные - это условное название.
mutagen, таким образом не должен выполнятся следующий код?
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ipstart = "172.18.9.";
$time_start = microtime(true);
for ($i = 0; $i < 10; $i++){
    // формируем ip адрес
    $ipadress = $ipstart."$i";
    // пингуем ip адрес
    exec("ping -n 2 -w 100 -4 ".$ipadress);
    // получаем ARP запись операционной системы с искомым ip адресом
    $find_str = '"'.$ipadress.' "';
    $exec_str = 'arp -a | findstr -C:'.$find_str;
    if ($output =! NULL) unset($output);
    exec($exec_str, $output);
    if ($output[0] != NULL) echo $output[0]."<br>";
    }
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br><br>Время выполнения - $time секунд";
работает как часы. можете проверить сами. правда долговато - у меня около 28 секунд ортрабатывает.
что скажете на это?
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 14:50
в теме про яву вы приводите в пример как работает php, можно также сказать и про shell скрипт
но это ничего не доказывает и не опровергает, так как в этих языках так делать можно и они выполняют команду как целую строку

в ява выполнение осуществляется не как строки, а как вызов бинарника и передача ему аргументов, вы передали в аргумент пайп (|), но разве он является аргументом программы arp?
нет! - он работает в шелле и перенаправляет вывод и когда ваш php выполняет эту команду он по сути вызывает шелл и передаёт ему строку и ждёт ответа, нет никакого контроля ошибок, нет кроссплатформенности, ещё много чего нет... неважно
правильно так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class PbExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder("arp", "-a");
        Process p = pb.start();
        p.waitFor();
        InputStream is = p.getInputStream();
        BufferedReader brin = new BufferedReader(new InputStreamReader(is));
        Pattern ip = Pattern.compile("([\\d\\.]+)");
 
        String response;
        while ((response = brin.readLine()) != null) {
            Matcher m = ip.matcher(response);
            if (m.find()) {
                System.out.println("I've found an IP: " + m.group(1));
                if(m.group(1).equals("172.18.9.2"))
                    System.out.println("I found my IP");
            }
        }
    }
}
хотя это тоже не совсем правильный подход - зависящий от наличия программы arp
0
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18
14.07.2012, 15:07  [ТС]
mutagen, спасибо за хороший пример, но задача ставилась не получить в результате exec() всю ARP таблицу и искать в ней одну строчку, а получить именно результат выполнения
Bash
1
arp -a | findstr -C:"172.18.9.2 "
В целом это связано с тем что нужно будет обработать таким образом около 2К ip адресов в минимальные сроки. Поиск необходимой строки в ARP таблице лучше переложить на ОС, т.к. она это сделает быстрее. Также это позволило бы сократить объемы данных, передаваемых моей программе командой.
да, я неправильно использовал команду консоли для своей задачи, сознаюсь в этом.
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 15:09
Цитата Сообщение от Шуршик Посмотреть сообщение
задача ставилась не получить в результате exec() всю ARP таблицу и искать в ней одну строчку, а получить именно результат выполнения
ну так и напишите регексп под вашу задачу, в чём проблема?

Цитата Сообщение от Шуршик Посмотреть сообщение
Поиск необходимой строки в ARP таблице лучше переложить на ОС, т.к. она это сделает быстрее.
я в этом сильно сомневаюсь, 2к это очень мало, у меня рекспы обрабатывали миллионы строк )
0
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18
14.07.2012, 15:32  [ТС]
проблема не в написании регулярного выражения, а в получении значений ip <-> MAC описанным выше способом о 2К узлах в течении, скажем 30 секунд.
ARP таблица хранит запись о каждом узле не более 2х минут, если он не используется повторно. доступность каждого из узлов определяется с помощью
Java
1
boolean isReached = InetAddress.getByName(ipadress).isReachable(1500);
при этом в ARP появлется запись о данном узле, если он конечно доступен.
эксперименты показывают что для моей сети isReachable(1500) можно уменьшить до 1100.
таким образом необходимо каждый раз сначала проверять доступность узла, а затем забирать его MAC из ARP таблицы.
таким образом, описанным вами методом задача сводится не к одиночному поиску в 2К строках, а к поискам 2К раз одной строки в 2К строках.
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 15:50
ану протестируйте, напихайте в лист пару тыщ IP и смотрите время
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class PbExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        List<InetAddress> ips = new LinkedList<InetAddress>();
        // пример
        ips.add(InetAddress.getByName("192.168.1.1"));
 
        ProcessBuilder pb = new ProcessBuilder("arp", "-a");
        Process p = pb.start();
        p.waitFor();
        InputStream is = p.getInputStream();
        BufferedReader brin = new BufferedReader(new InputStreamReader(is));
        Pattern ip = Pattern.compile("([\\d\\.]+).+?([abcdefABCDEF\\d:]+)");
        String response;
 
        for (InetAddress inetAddress : ips) {
            if (inetAddress.isReachable(1500)) {
                while ((response = brin.readLine()) != null) {
                    Matcher m = ip.matcher(response);
                    if (m.find()) {
                        if (inetAddress.equals(InetAddress.getByName(m.group(1)))) {
                            System.out.println("I've found an IP: " + m.group(1) + " it's MAC: " + m.group(2));
                        }
                    }
                }
            }
        }
    }
}
0
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18
14.07.2012, 17:01  [ТС]
протестировал.
добавал в ips несколько узлов.
из десяти адресов (4 из них пингуются) нашел только один.
время работы:
10 адресов - 13 с
20 адресов - 26 с
30 адресов - 38 с
40 адресов - подождал 2,5 минуты и остановил сам.
при выполнении каждого поиска находит только 1 адрес - 172.18.9.1 и MAC адрес выводится в виде 00.
кстати, если во время выполнения зависнет - потом не работает до тех пор, пока не перезагрузишь компьютер. пробовал выключать антивирус - не влияет.
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 17:37
тогда закешируем отвер арп кеша (это можно делать например раз в 2 минуты в программе актуализируя кеш)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class PbExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        List<InetAddress> ips = new LinkedList<InetAddress>();
        // пример
        ips.add(InetAddress.getByName("192.168.1.1"));
 
        ProcessBuilder pb = new ProcessBuilder("arp", "-a");
        Process p = pb.start();
        p.waitFor();
        InputStream is = p.getInputStream();
        BufferedReader brin = new BufferedReader(new InputStreamReader(is));
        Pattern ip = Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.+?\\d{1,3}).+((?:[a-fA-F\\d]{2}[:-]){5}(?:[A-Fa-f\\d]{2}))");
        String response;
        List<String> arpCache = new LinkedList<String>();
        while ((response = brin.readLine()) != null) {
            arpCache.add(response);
        }
        for (InetAddress inetAddress : ips) {
            if (inetAddress.isReachable(1500)) {
                for (String str : arpCache) {
                    System.out.println(str);
                    Matcher m = ip.matcher(str);
                    if (m.find()) {
                        if (inetAddress.equals(InetAddress.getByName(m.group(1)))) {
                            System.out.println("I've found an IP: " + m.group(1) + " it's MAC: " + m.group(2));
                        }
                    }
                }
            }
        }
    }
}
Добавлено через 6 минут
или даже лучше так
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class PbExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        List<InetAddress> ips = new LinkedList<InetAddress>();
        // пример
        ips.add(InetAddress.getByName("192.168.1.1"));
 
        ProcessBuilder pb = new ProcessBuilder("arp", "-a");
        Process p = pb.start();
        p.waitFor();
        InputStream is = p.getInputStream();
        BufferedReader brin = new BufferedReader(new InputStreamReader(is));
        Pattern ip = Pattern
                compile("((?:\\d{1,3}\\.){3}\\d{1,3}).+((?:[a-fA-F\\d]{2}[:-]){5}(?:[A-Fa-f\\d]{2}))");
        String response;
        Map<InetAddress, String> arpCache = new HashMap<InetAddress, String>();
        while ((response = brin.readLine()) != null) {
            Matcher m = ip.matcher(response);
            if (m.find())
                arpCache.put(InetAddress.getByName(m.group(1)), m.group(2));
        }
 
        for (InetAddress inetAddress : ips) {
            if (inetAddress.isReachable(1500)) {
                for (Iterator<InetAddress> iterator = arpCache.keySet().iterator(); iterator.hasNext();) {
                    InetAddress ipAddr = iterator.next();
                    if (ipAddr.equals(inetAddress))
                        System.out.println("I've found an IP: " + ipAddr.getHostAddress() + " it's MAC: " + arpCache.get(ipAddr));
                }
            }
        }
    }
}
1
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18
14.07.2012, 18:19  [ТС]
попробовал последний вариант:
время выполнения не изменилось.
также зависает (но реже), помогает только перезагрузка компьютера.
стал нормально находить и отображать ip - MAC, но бывает что пропускает один - два пингуемых адреса.
я попробовал свою методику (с правильным вызовом arp -a) - вполне работоспособно.
переделал на потоки - каждый поток обрабатывает свой ip адрес -получилось собрать данные о 100 адресах за 3 секунды.
думаю дальше справлюсь сам.
mutagen, БОЛЬШОЕ ВАМ СПАСИБО ЗА СОВЕТЫ, ПОМОЩЬ И НЕРАВНОДУШНОЕ ОТНОШЕНИЕ К ЧУЖИМ ПРОБЛЕМАМ!!!
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 18:51
Цитата Сообщение от Шуршик Посмотреть сообщение
время выполнения не изменилось.
оно в основном зависит от таймаута ожидания пинга 1500, паралельное выполнение при помощи потоков хорошее решение, как способ снизить общее время ожидания
1
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 19:09
я тоже накидал мультипоток, проверьте сколько времени
я проверить нормально не могу, так как у меня к сожалению мало IP в кеше

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class PbExample {
    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
        List<InetAddress> ips = new LinkedList<InetAddress>();
        // пример
        ips.add(InetAddress.getByName("192.168.1.1"));
 
        ProcessBuilder pb = new ProcessBuilder("arp", "-a");
        Process p = pb.start();
        p.waitFor();
        InputStream is = p.getInputStream();
        BufferedReader brin = new BufferedReader(new InputStreamReader(is));
        Pattern ip = Pattern.compile("((?:\\d{1,3}\\.){3}\\d{1,3}).+((?:[a-fA-F\\d]{2}[:-]){5}(?:[A-Fa-f\\d]{2}))");
        String response;
        Map<InetAddress, String> arpCache = new HashMap<InetAddress, String>();
        while ((response = brin.readLine()) != null) {
            Matcher m = ip.matcher(response);
            if (m.find())
                arpCache.put(InetAddress.getByName(m.group(1)), m.group(2));
        }
        ExecutorService es = Executors.newFixedThreadPool(100);
        List<Future<IpMac>> rezult = new LinkedList<Future<IpMac>>();
        for (InetAddress inetAddress : ips) {
            rezult.add(es.submit(new Pinger(inetAddress, arpCache)));
        }
        es.shutdown();
        IpMac ipMac;
        for (Future<IpMac> future : rezult) {
            ipMac = future.get();
            if (ipMac != null)
                System.out.println(ipMac.toString());
        }
    }
}
 
class IpMac {
    private String ip;
    private String mac;
 
    public String getIp() {
        return ip;
    }
 
    public void setIp(String ip) {
        this.ip = ip;
    }
 
    public String getMac() {
        return mac;
    }
 
    public void setMac(String mac) {
        this.mac = mac;
    }
 
    public IpMac(String ip, String mac) {
        this.ip = ip;
        this.mac = mac;
    }
 
    @Override
    public String toString() {
        return "[ip=" + ip + ", mac=" + mac + "]";
    }
 
}
 
class Pinger implements Callable<IpMac> {
    private InetAddress ip;
    private Map<InetAddress, String> arpCache;
 
    public Pinger(InetAddress ip, Map<InetAddress, String> arpCache) {
        this.ip = ip;
        this.arpCache = arpCache;
    }
 
    @Override
    public IpMac call() throws Exception {
        if (ip.isReachable(1500)) {
            for (Iterator<InetAddress> iterator = arpCache.keySet().iterator(); iterator.hasNext();) {
                InetAddress ipAddr = iterator.next();
                if (ipAddr.equals(ip)) {
                    return new IpMac(ip.getHostAddress(), arpCache.get(ipAddr));
                }
            }
        }
        return null;
    }
}
0
0 / 0 / 0
Регистрация: 29.09.2011
Сообщений: 18
14.07.2012, 21:03  [ТС]
проверил ваш вариант - время выполнения 3-4 секунды на 100 ip адресов.
но осталась проблема с зависанием во время выполнения - после повторной попытке запуска со 100 адресами произошло зависание (вывод NetBeans отображет run: и больше ничего не происходит). после перезагрузки заново запустить не удалось - то же самое зависание.

вот мой вариант:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class IpMacSearcher {
    
    public static void main(String[] args){
        String ip_start = "172.18.9.";
        List<FindMacTread> finderTreads = new ArrayList<>();
        for (int i = 0; i < 100; i++){
            finderTreads.add(new FindMacTread(ip_start + i));
            }
        for (FindMacTread t : finderTreads){
            t.start();
            }
        }
    
    }
 
public class FindMacTread extends Thread{
 
    protected String ipadress = "";
 
    FindMacTread(String ip) {
        ipadress = ip;
        }
    
    @Override
    public void run(){    
        try{
            find_ip_MAC f = new find_ip_MAC(ipadress);
            } 
        catch (UnknownHostException ex){
            Logger.getLogger(FindMacTread.class.getName()).log(Level.SEVERE, null, ex);
            } 
        catch (IOException | InterruptedException ex){
            Logger.getLogger(FindMacTread.class.getName()).log(Level.SEVERE, null, ex);
            }
        
    }
}
 
public class find_ip_MAC{
    
    protected String ipadress = "";
    protected String MAC = "";
    
    find_ip_MAC(String ip) throws UnknownHostException, IOException, InterruptedException{
        ipadress = ip;
        String result = findMAC();
        if (!result.isEmpty()) System.out.println(ipadress + " : " + findMAC());
        }
    
    private String findMAC() throws IOException{
        // проверяем доступность узла по адресу ipadress
        boolean isReached = InetAddress.getByName(ipadress).isReachable(2000);
        // получаем ARP запись операционной системы с искомым ip адресом
        if (isReached){
            Pattern pattern = Pattern.compile("(\\S\\S-){5}\\S\\S");
            String tmp;
            // формируем строку с командой для выполнения
            String cmd[] = {"arp", "-a", ipadress};
            // производим запуск команды arp -a "ipadress"
            Process find_MAC = Runtime.getRuntime().exec(cmd);
            InputStream inStream = find_MAC.getInputStream();
            BufferedReader outStream = new BufferedReader(new InputStreamReader(inStream));
            // в результатах выплнения команды exec() построчно ищем MAC адрес сетевого узла 
            while ((tmp = outStream.readLine()) != null){ 
                Matcher m = pattern.matcher(tmp);
                if (m.find()) MAC = m.group();
                }
            // закрываем потоки
            outStream.close();
            inStream.close();
            if (MAC.isEmpty()) return "";
            else return MAC;
            }
        else return MAC;
        }    
    }
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
14.07.2012, 22:21
подозреваю что зависание это уже проблема на уровне ОС, так как я на линуксе сколько не пробовал зависания не добился с кучей левых нагенерённых IP
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class PingerArp {
    private static Random rnd = new Random();
 
    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        List<InetAddress> ips = new LinkedList<InetAddress>();
        // пример
        ips.add(InetAddress.getByName("192.168.1.1"));
        for (int i = 0; i < 5000; i++) {
            ips.add(InetAddress.getByName(getRandomIP()));
        }
 
        ProcessBuilder pb = new ProcessBuilder("arp", "-a");
        Process p = pb.start();
        p.waitFor();
        InputStream is = p.getInputStream();
        BufferedReader brin = new BufferedReader(new InputStreamReader(is));
        Pattern ip = Pattern.compile("((?:\\d{1,3}\\.){3}\\d{1,3}).+((?:[a-fA-F\\d]{2}[:-]){5}(?:[A-Fa-f\\d]{2}))");
        String response;
        Map<InetAddress, String> arpCache = new HashMap<InetAddress, String>();
        while ((response = brin.readLine()) != null) {
            Matcher m = ip.matcher(response);
            if (m.find())
                arpCache.put(InetAddress.getByName(m.group(1)), m.group(2));
        }
        ExecutorService es = Executors.newFixedThreadPool(100);
        List<Future<IpMac>> rezult = new LinkedList<Future<IpMac>>();
        for (InetAddress inetAddress : ips) {
            rezult.add(es.submit(new Pinger(inetAddress, arpCache)));
        }
        es.shutdown();
        IpMac ipMac;
        for (Future<IpMac> future : rezult) {
            ipMac = future.get();
            if (ipMac != null)
                System.out.println(ipMac.toString());
        }
        long end = System.currentTimeMillis();
        System.out.println("time taken " + (end - start) / 1000 + " sec");
    }
 
    private static String getRandomIP() {
        StringBuilder sb = new StringBuilder();
        sb.append(rnd.nextInt(256)).append(".").append(rnd.nextInt(256)).append(".").append(rnd.nextInt(256))
                .append(".").append(rnd.nextInt(256));
        return sb.toString();
    }
 
}
 
class IpMac {
    private String ip;
    private String mac;
 
    public String getIp() {
        return ip;
    }
 
    public void setIp(String ip) {
        this.ip = ip;
    }
 
    public String getMac() {
        return mac;
    }
 
    public void setMac(String mac) {
        this.mac = mac;
    }
 
    public IpMac(String ip, String mac) {
        this.ip = ip;
        this.mac = mac;
    }
 
    @Override
    public String toString() {
        return "Found [ip=" + ip + ", mac=" + mac + "]";
    }
 
}
 
class Pinger implements Callable<IpMac> {
    private InetAddress ip;
    private Map<InetAddress, String> arpCache;
 
    public Pinger(InetAddress ip, Map<InetAddress, String> arpCache) {
        this.ip = ip;
        this.arpCache = arpCache;
    }
 
    @Override
    public IpMac call() throws Exception {
        if (ip.isReachable(1500)) {
            for (Iterator<InetAddress> iterator = arpCache.keySet().iterator(); iterator.hasNext();) {
                InetAddress ipAddr = iterator.next();
                if (ipAddr.equals(ip)) {
                    return new IpMac(ip.getHostAddress(), arpCache.get(ipAddr));
                }
            }
        }
        return null;
    }
}
Found [ip=192.168.1.1, mac=34:e5:ff:a2:56:91]
time taken 67 sec
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.07.2012, 22:21
Помогаю со студенческими работами здесь

Не отображать консоль при выполнении команды через exec
Здравствуйте, я кроном запускаю через exec консольную команду вот как она выглядит: $result = exec(__DIR__ . '/phantomjs ' . __DIR__ ....

Ошибка in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc)
Traceback (most recent call last): File &quot;&lt;input&gt;&quot;, line 1, in &lt;module&gt; File &quot;C:\Program Files\JetBrains\PyCharm...

Код не выполняется в одном месте, но выполняется в другом
Вот код процедуры: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; ...

Проект выполняется на Windows 8, но не выполняется на виртуальной машине
У меня есть проект, собранный в релиз, в котором осуществляется внедрение своей dll в память чужих процессов (после внедрения в DLL...

По краткому названию команды и фамилиям ее участников, построить полное название команды
Всем привет) Я тут решил полазить по http://********, что бы немножко потренероваться, и наткнулся на какую-ту фигню, помогите разобраться)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru