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

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

08.08.2014, 10:45. Показов 2402. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru