Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 25.02.08 15:25
Оценка:
Пытаюсь определить имя хоста по его айпи.

Соединение с хостом:
socket=new QTcpSocket();
//connect(socket, SIGNAL(connected()), this, SLOT(havePC()), Qt::DirectConnection);
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(haveError(QAbstractSocket::SocketError)), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
socket->connectToHost(hostIP, port);
socket->waitForConnected(timeout);
socket->disconnectFromHost();

Обработка соединения с хостом:
void PCLister::havePC()
{
QHostInfo info;
info.setHostName(socket->peerName());
//Здесь идет дальнейшая обработка
}

Вопрос в том, что имя компа по айпи не определяется . В socket->peerName() находится не имя, а собственно передаваемый при соединении IP. Кто-то знает, в чем может быть причина?
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re: Определение имени хоста по IP в Qt 4.3.3
От: Stuw  
Дата: 26.02.08 11:33
Оценка:
Здравствуйте, vasilchmax, Вы писали:

V>Пытаюсь определить имя хоста по его айпи.


V>Соединение с хостом:

V>socket=new QTcpSocket();
V>//connect(socket, SIGNAL(connected()), this, SLOT(havePC()), Qt::DirectConnection);
V>connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
V> this, SLOT(haveError(QAbstractSocket::SocketError)), Qt::DirectConnection);
V>connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
V>socket->connectToHost(hostIP, port);
V>socket->waitForConnected(timeout);
V>socket->disconnectFromHost();

V>Обработка соединения с хостом:

V>void PCLister::havePC()
V>{
V> QHostInfo info;
V> info.setHostName(socket->peerName());
V> //Здесь идет дальнейшая обработка
V>}

V>Вопрос в том, что имя компа по айпи не определяется . В socket->peerName() находится не имя, а собственно передаваемый при соединении IP. Кто-то знает, в чем может быть причина?


Имхо, если судить по идеологии класса, то ты можешь присоединиться к серверу указав его имя или ip адрес. Резолвить имя по ip адресу тут незачем.
Посмотри класс QHostInfo.
Re[2]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 26.02.08 15:39
Оценка:
Здравствуйте, Stuw, Вы писали:

S>Имхо, если судить по идеологии класса, то ты можешь присоединиться к серверу указав его имя или ip адрес. Резолвить имя по ip адресу тут незачем.

S>Посмотри класс QHostInfo.

Хм, а как же тогда получить нормально? Особенно если учитавать, что время получения ограничено в 100 мс, больше нежелательно, т.к. идет основной поток. Думал раньше реализовать через QHostInfo::lookupHost() причем в другом потоке, но возникли проблемы с передачей переменной QHostInfo в основной поток.
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re[3]: Определение имени хоста по IP в Qt 4.3.3
От: Michael Chelnokov Украина  
Дата: 26.02.08 15:56
Оценка: 2 (1)
Здравствуйте, vasilchmax, Вы писали:

V>Хм, а как же тогда получить нормально?


"Нормально" — никак. Кто тебе сказал что у твоего хоста вообще есть имя? Кто тебе сказал что оно у него одно?
Действительно ли тебе необходимо его получать? И что ты будешь делать, если получить все-таки не удастся?
Re[3]: Определение имени хоста по IP в Qt 4.3.3
От: Stuw  
Дата: 26.02.08 16:24
Оценка:
Здравствуйте, vasilchmax, Вы писали:

V>Здравствуйте, Stuw, Вы писали:


S>>Имхо, если судить по идеологии класса, то ты можешь присоединиться к серверу указав его имя или ip адрес. Резолвить имя по ip адресу тут незачем.

S>>Посмотри класс QHostInfo.

V>Хм, а как же тогда получить нормально? Особенно если учитавать, что время получения ограничено в 100 мс, больше нежелательно, т.к. идет основной поток. Думал раньше реализовать через QHostInfo::lookupHost() причем в другом потоке, но возникли проблемы с передачей переменной QHostInfo в основной поток.


То есть ты хочешь сказать, что у тебя соединение с удаленной машиной идет в основном потоке и ты хочешь уложиться в 100 мс?
Re[4]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 26.02.08 18:38
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

MC>"Нормально" — никак. Кто тебе сказал что у твоего хоста вообще есть имя? Кто тебе сказал что оно у него одно?

MC>Действительно ли тебе необходимо его получать? И что ты будешь делать, если получить все-таки не удастся?

Имя у хоста точно есть, т.к. все хосты из локалки и все названы. Причеем имя только одно, но это неважно, нужно найти хотя бы первое.
Получить очень даже желательно,т.к. я пишу сканер локалки на общие ресурсы и выводить список только из айпи не очень красиво получится
Если не найду... в принципе другие программы находят, я тоже по идее должен
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re[4]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 26.02.08 18:39
Оценка: :)
Здравствуйте, Stuw, Вы писали:

S>То есть ты хочешь сказать, что у тебя соединение с удаленной машиной идет в основном потоке и ты хочешь уложиться в 100 мс?


Да, чтобы ГУИ не зависало при определении. Думал с потоке сделать, но как раньше уже писал, возникают проблемы при передачи в основной поток параметров. В принципе параметр не только QHostInfo, но и еще много других.
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re[5]: Определение имени хоста по IP в Qt 4.3.3
От: Stuw  
Дата: 27.02.08 07:37
Оценка: 2 (1)
Здравствуйте, vasilchmax, Вы писали:

V>Здравствуйте, Stuw, Вы писали:


S>>То есть ты хочешь сказать, что у тебя соединение с удаленной машиной идет в основном потоке и ты хочешь уложиться в 100 мс?


V>Да, чтобы ГУИ не зависало при определении. Думал с потоке сделать, но как раньше уже писал, возникают проблемы при передачи в основной поток параметров. В принципе параметр не только QHostInfo, но и еще много других.


Вы пробовали конектится к несуществующему/выключенному хосту? В зависимости от того, какой стоит таймаут, процесс соединения может занять до полуминуты (на вскидку, более точные цыфры надо смотреть).

Лучше разобраться с многопоточностью. Расскажи какие проблемы при передаче параметров (и как собственно устроен вспомогательный поток), и возможно тебе помогут.

з.ы. Меня, например, очень бесит, когда приложение подвешивает гуй при коннекте ))
Re[6]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 27.02.08 13:17
Оценка:
С передачей параметров вроде разобрался. Оказалась, напутал с qRegisterMetaType(). Теперь возник вопрос немного другого характера, связанный с потоками.
Вот мой код:
//Запуск проверки хостов
//PClist — потомок QThread, ему передаются различные параметры соединения
for(int i=1; i < 254; i++)
{
PCList *pc_list=new PCList(netmask+QString::number(i)/*это IP*/,conn_port/,timeout, this);
pc_list->setObjectName(QString("pc_list%1").arg(i));

connect(pc_list, SIGNAL(lookedUp(const QHostInfo&,const QStringList&, const QList<QFileInfo>&)), this,
SLOT(addHostToList(const QHostInfo&,const QStringList&, const QList<QFileInfo>&)));
connect(this, SIGNAL(closed()), pc_list, SLOT(quit()));
connect(pc_list, SIGNAL(AllListed()), this, SLOT(AllListed()));
connect(pc_list, SIGNAL(started()), this, SLOT(incThreadsCounter()));
connect(pc_list, SIGNAL(finished()), this, SLOT(decThreadsCounter()));
pc_list->start();
QApplication::processEvents();

}

//Здесь запуск класс потока, который проверяет хосты
void PCList::run()
{
socket=new QTcpSocket();
timer= new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(quit()));
timer->start(timeout+50);
connect(socket, SIGNAL(connected()), this, SLOT(havePC()));
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
connect(socket, SIGNAL(error ( QAbstractSocket::SocketError)),this, SLOT(haveError(QAbstractSocket::SocketError)));
connect(socket, SIGNAL(disconnected()), this, SLOT(quit()));
socket->connectToHost(netmask, port);
exec();
}

//Обработка информации о хостах (слот для сигнала connected() сокета)
void PCList::havePC()
{
QHostInfo info;
info.setHostName(socket->peerName());
QDir dir;
dir.setPath("//"+info.hostName());
QList<QFileInfo> file_infos;
QStringList files=dir.entryList();
QFileInfo file_info;
foreach(QString file, files)
{
file_info.setFile(dir,file);
file_info.refresh();
file_infos.append(file_info);
}
emit lookedUp(info, files, file_infos);
socket->disconnectFromHost();
exit();
}

Я в многопоточном программировании не очень (так что сильно не бейте ), поэтому возможно (точнее наверняка ) что-то сделал не так. При таком коде все работает, но судя по всему неправильно. Потоки не получают свой цикл обработки событий, т.к. главный поток время от времени виснет И еще одно, почему-то после закрытия программы выпадает сообщение об ошибке "Cannot send event to objects owned by other thread".
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re[7]: Определение имени хоста по IP в Qt 4.3.3
От: Stuw  
Дата: 27.02.08 14:40
Оценка:
Здравствуйте, vasilchmax

V>Я в многопоточном программировании не очень (так что сильно не бейте ), поэтому возможно (точнее наверняка ) что-то сделал не так. При таком коде все работает, но судя по всему неправильно. Потоки не получают свой цикл обработки событий, т.к. главный поток время от времени виснет И еще одно, почему-то после закрытия программы выпадает сообщение об ошибке "Cannot send event to objects owned by other thread".


Проблема с потоками, если я не ошибаюсь в том, что ты устанавливаешь сигналы не в главном потоке. Вынеси инициализацию сигналов из функции run.
И почитай про многопоточность в Qt


Теперь про поиск.
Ты ищешь по фтп и пытаешься соединиться с фтп сервером?
У тебя запускается 254 дополнительных потока — это слишком круто для системы. У тебя все остальные приложения нормально работают, когда начинает выполняться этот код?

Добавлять компьютеры в список думаю лучше по мере поступения информации.
Варианты определения, которые я вижу:
1. Несколько потоков — на каждый поток диапазон адресов.
Проблема — долгий коннект к несуществующим компам может хорошо затормозить весь процесс определения (но можно поставить таймаут на коннект поменьше. для локалки должно прокатить)

2. Широковещательный пинг (на крайняк просто пинг)
Проблема: файрволы

3. Использование протоколов, которые подняты на всех компах локалки (а ля смб)

Некоторые оптимизации:
а. Сделать список индексируемых компьютеров (тех кто согласится индексироваться, либо свой список) и резолвить по этому списку (он сильно ограничит количество вариантов)

б. Сначала смотреть ARP таблицу

Вот результаты поиска по этому сайту.
WNetOpenEnum, WNetEnumResource и WNetCloseEnum. Но это работает только если включен NETBIOS через TCP/IP
Автор: valager
Дата: 29.03.07

Вывод всех компьютеров сети
Автор: bacho_sun
Дата: 17.11.05

список включенных компьютеров рабочей группы
Автор: Mel
Дата: 28.10.03
Re[8]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 27.02.08 18:19
Оценка:
Попробую сделать инициализацию сигналов в главном потоке. Статью по ссылке читал (входит в QAssistant)
Теперь про поиск.
Я ищу не список ФТП (но можно и ФТП тоже искать ), а список обычных расшареных ресурсов. Все потоки, которые запускаются, практически сразу удалаются, после того, как соединяются с компом и получают список ресурсов и другой информации.
По вопросам:
1. Можно попытаться
2. А как его реализовать в Qt не подскажете?
3. Не очень знаю как сделать . В принципе на 90+% компов стоит Windows, но есть и *nix'ы.

На счет оптимизаций.
а. Не имеет смысла. В сети 200+ компов в одном сетевом диапазоне, причем количество растет.
б. Попробую.

И еще одно. Непонятно почему socket->peerName(); в 3-ей функции не имя хоста, а его ИП
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re[9]: Определение имени хоста по IP в Qt 4.3.3
От: Stuw  
Дата: 28.02.08 09:20
Оценка:
Здравствуйте, vasilchmax, Вы писали:

V>Попробую сделать инициализацию сигналов в главном потоке. Статью по ссылке читал (входит в QAssistant)

V>Теперь про поиск.
V>Я ищу не список ФТП (но можно и ФТП тоже искать ), а список обычных расшареных ресурсов. Все потоки, которые запускаются, практически сразу удалаются, после того, как соединяются с компом и получают список ресурсов и другой информации.
Если в одно время запущено много потоков, то системе будет тяжко.

V>По вопросам:

V>1. Можно попытаться
V>2. А как его реализовать в Qt не подскажете?
пинг чисто с помощью qt никак — http://lists.trolltech.com/qt-interest/2002-10/thread00351-0.html

V>3. Не очень знаю как сделать . В принципе на 90+% компов стоит Windows, но есть и *nix'ы.

Например, если попытка получить список расшареных ресурсов провалилась, считать комп отключенным. (ты же уже как-то получаешь список ресурсов?)

V>На счет оптимизаций.

V>а. Не имеет смысла. В сети 200+ компов в одном сетевом диапазоне, причем количество растет.
V>б. Попробую.

А вообще расскажи, что ты хочешь от поисковика по локалке? как планируешь организовать индексирование и собственно сам поиск?
проще будет выбирать технологии, которые тебе есть смысл использовать. Структура и организация сети (если она не секретная) тоже может помочь.

Я бы делал поисковик так:

1. Индексирование
Для каждого ip в сети, пытался получить список ресурсов. Если ресурсы есть, индексирую их и сохраняю ip (и имя до кучи, если смогу определить) в список доступных машин (оптимизация а).

2. Поиск
Собственно поиск и определение доступна ли машина из списка машин, на котором найдены ресурсы.

При такой схеме, не нужно морочиться с получением списка всех доступных машин в сети при поиске. Это происходит на этапе индексирования, а оно может быть не завязано на gui и временные ограничения здесь не кретичны. Соответственно переиндексировать сеть через какой-то промежуток времени.


V>И еще одно. Непонятно почему socket->peerName(); в 3-ей функции не имя хоста, а его ИП


Я конечно не проверял, но думаю, что если ты будешь конектиться по имени к компу, то эта функция вернет имя машины. Если же ты конектишься по ip, то класс QSocket не будет определять для тебя имя, и эта функция вернет ip.
Re[10]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 28.02.08 16:59
Оценка:
Здравствуйте, Stuw, Вы писали:
S>Если в одно время запущено много потоков, то системе будет тяжко.
Согласен, наверное сделаю несколько потоков и каждый будет обрабатывать диапазон машин.

S>пинг чисто с помощью qt никак — http://lists.trolltech.com/qt-interest/2002-10/thread00351-0.html

Попробую реализовать с помощью исходнка из статейки, может получится.


S>Например, если попытка получить список расшареных ресурсов провалилась, считать комп отключенным. (ты же уже как-то получаешь список ресурсов?)

Ну, в принципе у меня если к компу не могу приконнектится, то он и так считается отключенным

S>А вообще расскажи, что ты хочешь от поисковика по локалке? как планируешь организовать индексирование и собственно сам поиск?

Для начала хотя бы просто вывести список компов и соответствующий список их ресурсов (если есть). Поиск и пр. пока в проект не входят

S>Для каждого ip в сети, пытался получить список ресурсов. Если ресурсы есть, индексирую их и сохраняю ip (и имя до кучи, если смогу определить) в список доступных машин (оптимизация а).

Так наверное и сделаю

S>Собственно поиск и определение доступна ли машина из списка машин, на котором найдены ресурсы.

Но я думаю в любом случае придется как минимум пинговать машины не из списка,т.к. может во время первой проверки машина просто была выключена.

V>>И еще одно. Непонятно почему socket->peerName(); в 3-ей функции не имя хоста, а его ИП


S>Я конечно не проверял, но думаю, что если ты будешь конектиться по имени к компу, то эта функция вернет имя машины. Если же ты конектишься по ip, то класс QSocket не будет определять для тебя имя, и эта функция вернет ip.

Наверное так и есть
... << RSDN@Home 1.2.0 alpha rev. 789>>
Re[11]: Определение имени хоста по IP в Qt 4.3.3
От: Stuw  
Дата: 28.02.08 19:58
Оценка:
Здравствуйте, vasilchmax, Вы писали:

V>Для начала хотя бы просто вывести список компов и соответствующий список их ресурсов (если есть). Поиск и пр. пока в проект не входят


Смотри Вопрос №4
Re[7]: Определение имени хоста по IP в Qt 4.3.3
От: oziro Нигерия  
Дата: 29.02.08 23:43
Оценка:
Пожалуйста, выделяйте код специальным тегом!

[ccode] ВАШ КОД на языке с++ [/ccode]
Re[8]: Определение имени хоста по IP в Qt 4.3.3
От: vasilchmax  
Дата: 03.03.08 21:57
Оценка:
Здравствуйте, oziro, Вы писали:

O>Пожалуйста, выделяйте код специальным тегом!


O>[ccode] ВАШ КОД на языке с++ [/ccode]


Спасибо за подсказку, просто тег не знал.
... << RSDN@Home 1.2.0 alpha rev. 789>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.