Russian Qt Forum

Qt => Работа с сетью => Тема начата: BaHeK от Ноябрь 16, 2011, 09:17



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

Скрин с ноутбука:
(http://s2.ipicture.ru/uploads/20111116/HTo1Z3xx.png)

Скрин с домашнего:
(http://s2.ipicture.ru/uploads/20111116/VdjTtwNW.png)

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

Код:
        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;

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

    }
}


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: lesav от Ноябрь 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 пакетом. Если ответа нет(лучше нескольких ответов), удалять из списка.


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: lesav от Ноябрь 16, 2011, 22:07
А при закрытии программы разослать всем уведомление типа  "Досвидос".


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


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: BaHeK от Ноябрь 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!");
}

Не знаю что придумать...


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: _OLEGator_ от Ноябрь 17, 2011, 10:37
а не может быть проблемы в нескольких сетевых интерфейсах?


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: BaHeK от Ноябрь 17, 2011, 16:27
а не может быть проблемы в нескольких сетевых интерфейсах?

А это уже интересно... посмотрю...  :)


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: Странник от Ноябрь 18, 2011, 00:40
да, QHostAddress::Broadcast лучше не использовать - в случае нескольких интерфейсов пакеты могут отсылаться только с первого интерфейса, поддерживающего широковещание. попробуйте явно указывать широковещательный адрес сети, в которую посылаете запрос.


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

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


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: BaHeK от Ноябрь 22, 2011, 13:21
Решено!!!  :)
Рассказываю как отмучался... дело было все-таки в сетевых интерфейсах, поотключал практически все, кроме "Подключение по локальной сети", стало работать нормально, но стали проблемы появляться с обнаружением этого компьютера, снес WmWare, не помогло, снес Hamachi, мне в момент удаления выдало сообщение о том, что данный тунель ипользуется!! Вот тут то и понятно стало, что это все данные в него уходили...
Вопрос с тем, что программа больше одного пакета не посала оказался в том, что когда пакет приходил, выводилось QMessageBox, который временно приостанавливал работу приложения... выбросил эти диалоги все, и окошки лишние, стало нормально все работать....
Все просто, а как не знаешь куда копать, то вот такая картина и получается... Спасибо всем! потом может само "приложение" положу, на общую рецензию...


Название: Re: QUdpSocket проблемы с обнаружением...
Отправлено: Странник от Декабрь 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-адресам.