Russian Qt Forum
Ноябрь 23, 2024, 21:08 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QUdpSocket проблемы с обнаружением...  (Прочитано 8452 раз)
BaHeK
Гость
« : Ноябрь 16, 2011, 09:17 »

Здравствуйте! По учебе возникла мне необходимость сделать одно хитрое сетевое приложение... суть задания излагать не буду, мало кому оно все-равно будет интересно, но вот основные аспекты которые меня уже начинают немного напрягать и я не знаю как это решить далее.... В общем:
Используя UDP сокеты нужно мне обнаружить всех клиентов... Тоесть программа запускается на нескольких компьютерах, и используя широковещательную рассылку каждый клиент видит кто в сети... Возникла следующая ситуация..
1. На работе... Запускаю программу на рабочем компьютере, на своем ноутбуке, еще на компьютере, и еще на одном... Получается так, что мой рабочий компьютер видит всех, а они все его не видят, а все остальное окружение работает нормально...
2. Дома... Запускаю на домашнем компьютере, на ноутбуке и на еще одном компьютере... Получается такая же картина, но уже в центре внимания получается мой ноутбук!! Теперь он видит все, а его никто не видит....

Скрин с ноутбука:


Скрин с домашнего:


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

Код:
        m_pUDPSocket = new QUdpSocket(this);
        m_pUDPSocket->bind(QHostAddress::Any, m_nPort);

        sendImOnline();
        connect(m_pUDPSocket, SIGNAL(readyRead()), SLOT(slotReadData()));

        m_pTimer = new QTimer;
        m_pTimer->start(1000);

        connect(m_pTimer, SIGNAL(timeout()), SLOT(slotSendImOnline()));

Код:
void MainWindow::sendImOnline()
{
    QByteArray byteArray;
    QDataStream dataOut(&byteArray, QIODevice::WriteOnly);
    dataOut<<IM_ONLINE;
    dataOut<<m_sUserName;

    m_pUDPSocket->writeDatagram(
                  byteArray
                , QHostAddress::Broadcast
                , m_nPort
                );
}

Код:
void MainWindow::slotReadData()
{
    QByteArray byteArray;
    byteArray.resize(m_pUDPSocket->pendingDatagramSize());

    QHostAddress hostAdress;
    m_pUDPSocket->readDatagram(byteArray.data(), byteArray.size(), &hostAdress, &m_nPort);

    QDataStream dataIn(&byteArray, QIODevice::ReadOnly);
    qint32 nRequestOrMessageType;
    dataIn>>nRequestOrMessageType;

    ..... ля ля ля, еще код .....

    }
}
Записан
lesav
Частый гость
***
Offline Offline

Сообщений: 235


qnx.org.ru


Просмотр профиля WWW
« Ответ #1 : Ноябрь 16, 2011, 22:00 »

Я бы поменял местами следующие строки
Код
C++ (Qt)
       sendImOnline();
       connect(m_pUDPSocket, SIGNAL(readyRead()), SLOT(slotReadData()));
Но, судя по наличию
Код
C++ (Qt)
       connect(m_pTimer, SIGNAL(timeout()), SLOT(slotSendImOnline()));
это на функционал не повлияет, но выглядит как-то лаконичней.

И теперь мои домыслы:
А если попробовать высылать широковещанием имена и ip всех кого вижу в сети ?

А на стороне приема сохранить ip адреса и по таймеру пинговать их udp пакетом. Если ответа нет(лучше нескольких ответов), удалять из списка.
Записан

lesav
Частый гость
***
Offline Offline

Сообщений: 235


qnx.org.ru


Просмотр профиля WWW
« Ответ #2 : Ноябрь 16, 2011, 22:07 »

А при закрытии программы разослать всем уведомление типа  "Досвидос".


На широковещании могут сказываться политики заложенные в маршрутизаторы или файрволы компьютеров.
Записан

BaHeK
Гость
« Ответ #3 : Ноябрь 17, 2011, 09:28 »

Здравствуйте! Спасибо за ответ! Файрволы не используются... Насчет маршрутизации не могу ничего сказать...

Тут такая картина получается... Дебажил, поставил чтобы выводило на консоль qDebug()<<имя того, кто посылает пакет; и получается так, что пакеты этой "белой вороны" они попросту никому не доходят... они приходят только самому ему и все... а от остальных он принимает нормально.... Может я както неправильно излагаю свою проблему, вы скажите, добавлю информации, но просто я понять не могу, почему один и тотже компьютер на работе в сети нормально видит всех (ноутбук мой, например), а один какойто остается в неведении.. Дома, этот "всевидящий" ноутбук, становится слепым....
Вчера сделал раздельно клиент и сервер, и таже картина, запустил сервер на домашнем, клиент на ноутбуке... Сервер не принял ни одного сигнала, поменял местами, пакет дошел, но только 1... это кстати уже второй вопрос....почему только 1 пакет...  Непонимающий Непонимающий В замешательстве Плачущий
Клиент:
Код:
void Client::sendImOnlineMessage()
{
    QByteArray byteArray;
    QDataStream dataOut(&byteArray, QIODevice::WriteOnly);
    dataOut<<quint8(0);
    dataOut<<m_sLocalHostName;

    m_pUdpSocket->writeDatagram(
                  byteArray
                , QHostAddress::Broadcast
                , m_nPort
                );
}

Таже картина с таймером на посылку IM_ONLINE синала
Код:
   m_pUdpSocket = new QUdpSocket;
   m_pUdpSocket->bind(QHostAddress::Any, m_nPort);

Сервер:
Код:
   m_pUdpSocket = new QUdpSocket;
   m_pUdpSocket->bind(QHostAddress::Any, m_nPort);

   connect(m_pUdpSocket, SIGNAL(readyRead()), SLOT(slotReadMessage()));

Код:
void Server::slotReadMessage()
{
    QMessageBox::information(this, "...", "Got message!");
}

Не знаю что придумать...
Записан
_OLEGator_
Гость
« Ответ #4 : Ноябрь 17, 2011, 10:37 »

а не может быть проблемы в нескольких сетевых интерфейсах?
Записан
BaHeK
Гость
« Ответ #5 : Ноябрь 17, 2011, 16:27 »

а не может быть проблемы в нескольких сетевых интерфейсах?

А это уже интересно... посмотрю...  Улыбающийся
Записан
Странник
Гость
« Ответ #6 : Ноябрь 18, 2011, 00:40 »

да, QHostAddress::Broadcast лучше не использовать - в случае нескольких интерфейсов пакеты могут отсылаться только с первого интерфейса, поддерживающего широковещание. попробуйте явно указывать широковещательный адрес сети, в которую посылаете запрос.
Записан
BaHeK
Гость
« Ответ #7 : Ноябрь 21, 2011, 11:24 »

да, QHostAddress::Broadcast лучше не использовать - в случае нескольких интерфейсов пакеты могут отсылаться только с первого интерфейса, поддерживающего широковещание. попробуйте явно указывать широковещательный адрес сети, в которую посылаете запрос.

Я пробовал некоторые варианты с адресами, может вы можете показать на своем примере, ато я уже не знаю точно, может я так и делал уже, но не понял, что именно так правильно... заранее спасибо!
Записан
BaHeK
Гость
« Ответ #8 : Ноябрь 22, 2011, 13:21 »

Решено!!!  Улыбающийся
Рассказываю как отмучался... дело было все-таки в сетевых интерфейсах, поотключал практически все, кроме "Подключение по локальной сети", стало работать нормально, но стали проблемы появляться с обнаружением этого компьютера, снес WmWare, не помогло, снес Hamachi, мне в момент удаления выдало сообщение о том, что данный тунель ипользуется!! Вот тут то и понятно стало, что это все данные в него уходили...
Вопрос с тем, что программа больше одного пакета не посала оказался в том, что когда пакет приходил, выводилось QMessageBox, который временно приостанавливал работу приложения... выбросил эти диалоги все, и окошки лишние, стало нормально все работать....
Все просто, а как не знаешь куда копать, то вот такая картина и получается... Спасибо всем! потом может само "приложение" положу, на общую рецензию...
Записан
Странник
Гость
« Ответ #9 : Декабрь 04, 2011, 13:57 »

Я пробовал некоторые варианты с адресами, может вы можете показать на своем примере, ато я уже не знаю точно, может я так и делал уже, но не понял, что именно так правильно... заранее спасибо!
собственно, на работе я использую QUdpSocket для рассылки широковещательных запросов в локальной сети 192.168.0.0/24. сначала отправлял на адрес QHostAddress::Broadcast (он же 255.255.255.255). если на машине один сетевой интерфейс, все работало замечательно. при подключении VPN или появлении сетевого адаптера VMWare пакеты с машины продолжали уходить, но приемники их не получали - при такой конфигурации пакеты отправлялись только с первого сетевого интерфейса, а не со всех, как я ожидал. проблема решилась, когда я стал отправлять пакеты на 192.168.0.255 - broadcast-адрес нужной мне сети 192.168.0.0/24. если вам нужно рассылать во все доступные сети, надежнее будет в цикле делать отправку по их broadcast-адресам.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.081 секунд. Запросов: 22.