С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 8

Список хостов локальной сети, или как синхронизировать?

08.08.2014, 10:45. Показов 2398. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Читающим привет!
Пишу небольшое сетевое приложение (ну как пишу - продираюсь через дебри)
Возникла необходимость построить список доступных хостов, получилось вот что
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
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
 
public class NetScanner extends Thread {
 
    private String ip;
    public static List<String> address;
    
    Logger log = Logger.getAnonymousLogger();
            
    public NetScanner(String ip) {
        this.ip = ip;
    }
      
    public void run() {
        try {
            //InetAddress addr = InetAddress.getByName(ip);
            //boolean r = addr.isReachable(null,255,1000);
 
            Process process = Runtime.getRuntime().exec("C:/WINDOWS/system32/ping.exe "+ip);
            process.waitFor();
            InputStream is = process.getInputStream();
            StringBuilder sb = new StringBuilder();
            byte[] buf = new byte[1024];
            while( is.available() > 0 ) {
                int read = is.read(buf);
                if( read < 0 ) break;
                sb.append(new String(buf,0,read,"866"));
            }
            is.close();
            log.info(sb.toString());
 
            if( sb.toString().indexOf("недоступен") < 0 ) {
                synchronized (address){
                    address.add(ip);
                    System.out.println(address.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
                 
    public static List<String> ListOnLine() throws InterruptedException {
        String net = "192.168.0.";
        System.out.println("Running...");
        for(int i=1; i<5; i++){
            new  NetScanner(net+i).start();
            Thread.sleep(500);
        }
        return address;
    }
    
    public static void main(String[] args) throws IOException, InterruptedException {
        address = new ArrayList<String>();
        if(address == null){
           System.out.println(" Туфтень " );
        }
        else {
            for(String l:ListOnLine()){
                System.out.println(l+" On line " );
            }
        }
    }
 
}
Проблемы 2:
Первая нашлась, когда я еще не использовала пинг и пользовалась методом класса InetAddress - isReachable, появляются жуткие задержки, приходится тормозить потоки на 5-6сек. Реально количество найденных онлайн зависит от Thread.sleep(); весьма. При задержке в 3 секунды конечно находит большинство, но елки не всех! и даже на 1 подсеть это 5-10 минут поиска.
Вторая обнаружилась, потому что забыла закомментировать
Java
1
boolean r = addr.isReachable(null,255,1000);
Пинги выполнялись все, а вот переменная address заполнялась черте чем, когда убрала эту строку вроде наладилось, но проблема то очевидно осталась, где-нибудь что-нибудь подвиснет и на тебе ошибочный список.

Кстати перебор адресов пингом можно пройти в 1 потоке чтобы не мучаться с синхронизацией, но тоже долго выходит.
Можно ли решить задачу не используя ping как таковой?
Куда копать товарисчи?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.08.2014, 10:45
Ответы с готовыми решениями:

Как синхронизировать время на двух компьютерах локальной сети?
Есть &quot;главный&quot; компьютер на котором время контролируется и подстраивается регулярно вручную или через интернет. И есть несколько других...

Определить диапазон используемых адресов хостов локальной сети
Здравствуйте! Помогите определить диапазон используемых адресов хостов локальной сети класса (использовать команду ping).

Как получить список IP-адресов или имён хостов некоторого сетевого домена?
Какими средствами можно получить список IP-адресов или имён хостов некоторого сетевого домена? То есть, если мне известно только имя...

9
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 8
14.08.2014, 12:21  [ТС]
Ответ кстати элементарный, нашла таки сама.
Дело в объявлении переменной address, должно быть
Java
1
public volatile static List<String> address;
нельзя ожидать что код
Java
1
2
3
synchronized (address){
        address.add(ip);
     }
будет работать корректно с не совсем правильно объявленной переменной.
Пока оставлю как есть, дело свое этот класс делает, но тему закрывать рано, все-таки не слишком это изящный способ, спамить пингами. Должно быть нормальное взрослое решение.
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
14.08.2014, 12:36
Ksyuhen, Вы сделали неправильный вывод. synchronized отлично работает и без указания volatile.
Основная проблема в том, что вы читаете переменную address через гонку.

Мне не понятно, зачем вы используете Thread.sleep вообще?
Для ожидания завершения потока проще (и правильней) использовать метод Thread.join
Если вы вызовите Thread.join для всех запущенных потоков и уберёте volatile - всё будет работать.
0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 8
14.08.2014, 15:41  [ТС]
synchronized отлично работает и без указания volatile
turbanoff, вы правы работает, но переменная в моем случае заполнялась неправильно, некоторые доступные хосты туда просто не попадали, модификатор volatile исправил ситуацию и код именно для гонки получается вполне рабочий, даже если совсем опустить Thread.sleep и не вспоминать про Thread.join.
Thread.join попробовала использовать, как вы посоветовали, действительно работает без volatile и выдает тот же результат, но получается медленнее и начала проскакивать ошибка
Java
1
2
3
4
5
6
7
8
9
10
11
java.io.IOException: Cannot run program "C:/WINDOWS/system32/ping.exe": CreateProcess error=8, Недостаточно памяти для обработки команды
    at java.lang.ProcessBuilder.start(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at operation.NetScanner.run(NetScanner.java:26)
Caused by: java.io.IOException: CreateProcess error=8, Недостаточно памяти для обработки команды
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
    ... 5 more
Мне не понятно, зачем вы используете Thread.sleep вообще?
Сейчас он остался как пережиток стартовой версии класса. Убрала.
А в стартовой у меня были проблемы с ожиданием отработки метода isReadable, ничего лучше sleep на тот момент, к сожалению, в голову не пришло.
0
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
14.08.2014, 16:16
не совсем в тему, но
можно запускать пинги не по 4 пакета по умолчанию и не ждать по 1000 мс пока вернется ответ, а сделать так
Code
1
ping -n 1 -w 400 192.168.0.2
n количество пакетов
w время ожидания ответа в мс
1
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 8
14.08.2014, 16:46  [ТС]
Паблито, спасибо, здорово ускоряет процесс.

С ошибкой про недостаточно памяти разобралась, просто неверно употребила join() (да и такое бывает ). Сейчас это работает вот здесь
Java
1
2
3
4
5
6
7
8
9
10
public static  List<String> ListOnLine() throws InterruptedException {
        String net = "192.168.0.";
        address = new ArrayList<String>();
        for(int i=1; i<255; i++){
            Thread ns = new  NetScanner(net+i);
            ns.start();
            ns.join();
        }
        return address;
    }
Потоки выполняются друг за другом и даже с ускорение пинга, подсказанного Паблито, получается гораааздо медленнее чем с гонкой
0
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
14.08.2014, 17:16
Я не в курсе что там реально за задача, но когда у меня возникает необходимость быстро просканировать всю подсеть, то я делаю примерно так:
Code
1
for /l %x in (1,1,254) do ping -n 1 -w 50 192.168.0.%x | find /I "TTL"
Из java код вообще убрать проверки на "reachable".

Во-первых так проще, из командного окна будет "прилетать" текст только если хост доступен.
Во-вторых на русском виндовсе ответ будет совсем другим.
Для локальной сети, я думаю, задержку можно поставить и в 50мс или даже меньше, это же не WAN.

То есть эта строка будет показывать нам только те хосты, которые доступны.
И останется проблема, как быть с хостами, которые не отвечают на ICMP пакеты намеренно.

И забыл сказать, это все в одной Thread
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
14.08.2014, 18:25
Ksyuhen, Вам надо вызвать join - вне цикла. Иначе смысла от потоков очень не много.
Цитата Сообщение от Ksyuhen Посмотреть сообщение
модификатор volatile исправил ситуацию и код именно для гонки получается вполне рабочий
Вам просто повезло, не более того. Если бы вы воткнули после каждой строчки Thread.sleep(10000) - результат был бы аналогичный.

Вообще я бы порекомендовал вам использовать Concurrent коллекции, например ConcurrentLinkedQueue, вместо этих плясок с synchronized и volatile
1
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 8
14.08.2014, 19:05  [ТС]
Цитата Сообщение от turbanoff Посмотреть сообщение
Вам надо вызвать join - вне цикла. Иначе смысла от потоков очень не много.
А подробнее можно? Все-таки теоретическая база несколько подводит. Ведь метод не статический, и я так поняла, его нужно применять к конкретному объекту. Покажите, пожалуйста, как вне цикла показать ожидание прерывания конкретного потока или как сделать вами написанное
Цитата Сообщение от turbanoff Посмотреть сообщение
Если вы вызовите Thread.join для всех запущенных потоков
Цитата Сообщение от turbanoff Посмотреть сообщение
Вообще я бы порекомендовал вам использовать Concurrent коллекции, например ConcurrentLinkedQueue, вместо этих плясок с synchronized и volatile
Вот за это спасибо, ведь вопрос не столько в правке кода, я только учусь и мне не хватает знаний в выборе оптимальных средств
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
14.08.2014, 19:36
Ksyuhen, Сохраните ваши Thread в каком-нибудь списке. А после основного цикла добавьте еще один цикл, в котором будуте перебирать элементы этого списка и вызывать join().
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.08.2014, 19:36
Помогаю со студенческими работами здесь

Как вытянуть список компьютеров из локальной сети?
Люди добрые помогите пож..) (VB5 Pro) Мне тут надо каким-то образом вытащить в массив список компьютеров в сети... сеть работает по...

Как получить список всех компов в локальной сети?
Как получить список всех компов в локальной сети?

Как получить список всех IP-адресов из локальной сети?
Уже пробовал QNetworkInterface::allAddresses(), но он почему-то выводит только 4 адреса, которые по видимому относятся только к локальной...

Как узнать имя или ip адрес атакующего по локальной сети?
Представим, что в помещении есть 3 ПК и один из них решил пошутить и прописать shutdown, но программа блокирует его действие, это очень...

Гейт или как дать доступ с другого диапазона локальной сети
Всем привет. Имеется 2 локальные сети. Между собой у них никак не связан доступ. Например в сети №1 на хостинге стоит сайт. Так вот...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru