crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Проверка соединения точка-точка на одной машине, тест сетевых адаптеров
MedEx
  опции профиля:
сообщение 11.5.2011, 11:09
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 11.2.2011
Пользователь №: 2403

Спасибо сказали: 0 раз(а)




Репутация:   0  


Здравствуйте!
Подскажите, на машине установлены несколько сетевых адаптеров, некоторые соединены точка-точка, некоторые подключены к хабу. Необходимо проверить пары точка-точка и внешнее подключение.
1. Составил список IP адресов адептеров на машине.
2. Пытаюсь на адреса из списка послать броадкаст пакет от выбранного адаптера. Затем от следующего из списка и так до конца. По идее должен получиться список пар из тех кто принят пакет (соединённых точка-точка). В обработчик попадают все адаптеры даже не соединённые физически друг с другом. Видимо на уровне драйвера происходит переадресация не доходя до канального уровня. Делал примерно ту же задачу но на Builder C++ 2010, всё было легко и просто UDP сокет, мультикаст, отправка пакета по списку. В обработчике читаю от кого в сокете кому - составил пару и вывел на экран. Может дело именно в мультикасте?
Код на qt
**********************************
<*.h>
QList<QUdpSocket *> UdpSocketList;
**********************************
<*.cpp>
#include "mainwindow.h"
#include "ui_mainwindow.h"
//------------------------------------------------------------------------------------
MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QStringList items;
    foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
        {
           if (interface.flags().testFlag(QNetworkInterface::IsRunning))
           foreach (QNetworkAddressEntry entry, interface.addressEntries())
             {
                    if ( interface.hardwareAddress() != "00:00:00:00:00:00"
                         && entry.ip().toString().contains(".")
                         && entry.ip().toString()!="127.0.0.1")
                    items << entry.ip().toString();
             }
        }

    for(int i=0;i<items.size();i++)
    {
        QUdpSocket * udpSocketS = new QUdpSocket(this);
        if(!udpSocketS->bind(QHostAddress(items[i]),9090+i,QUdpSocket::DefaultForPlatform))continue;
        UdpSocketList << udpSocketS;        
        connect(UdpSocketList.back(), SIGNAL(readyRead()),this, SLOT(RecvDatagrams()));
    }
}
//-------------------------------------------------------------------------------------------
MainWindow::~MainWindow()
{
    delete ui;

    for(int i=0;i<UdpSocketList.size();i++)
    {
        delete UdpSocketList[i];
    }
}
//----------------------------------------------------------------------------
void MainWindow::B_Start()
{
    QByteArray datagram;
    datagram.resize(64);

    for(int i=0;i<UdpSocketList.size();i++)
    {
       UdpSocketList[i]->writeDatagram(datagram.data(), datagram.size(),QHostAddress::Broadcast, 7);
       for(int j=0;j<UdpSocketList.size();j++)
       UdpSocketList[i]->writeDatagram(datagram.data(), datagram.size(),UdpSocketList[j]->localAddress(), 9090+j);
    }
    
}

//обработчик получения пакета на udp сокет
void MainWindow::RecvDatagrams()
{
    for(int i=0;i<UdpSocketList.size();i++)
    while (UdpSocketList[i]->hasPendingDatagrams())
    {
             QByteArray datagram;
             QHostAddress sender;
             quint16 Port;

             do {
                     datagram.resize(UdpSocketList[i]->pendingDatagramSize());
                     UdpSocketList[i]->readDatagram(datagram.data(), datagram.size(),&sender,&Port);

                     if(sender.toString()==UdpSocketList[i]->localAddress().toString())continue;

                     ui->TB_ViewText->addItem(QString("sender %1_%2 - %3_%4 resiver")
                                              .arg(sender.toString())
                                              .arg(Port)
                                              .arg(UdpSocketList[i]->localAddress().toString())
                                              .arg(UdpSocketList[i]->localPort()));
                 }
             while (UdpSocketList[i]->hasPendingDatagrams());
    }
}

**********************************

участвуют 3 адаптера :
1. 192.168.50.2 связан точка-точка с 192.168.50.3
2. 192.168.50.3 связан точка-точка с 192.168.50.2

3. 192.168.3.43 подключен к хабу

результат
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MedEx
  опции профиля:
сообщение 18.5.2011, 10:18
Сообщение #2


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 11.2.2011
Пользователь №: 2403

Спасибо сказали: 0 раз(а)




Репутация:   0  


Опытным путём удалось установить , что пакеты адресованные адаптерам установленным на одной машине (TCP,UDP) отправляются сокету напрямую через драйвер. Если сокет забинден на адрес и порт и есть джоин на групповой адрес у отправителя и получателя, то пакет идёт на канальный уровень.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MedEx
  опции профиля:
сообщение 20.5.2011, 8:22
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 11.2.2011
Пользователь №: 2403

Спасибо сказали: 0 раз(а)




Репутация:   0  


Камрады поделитесь рабочим примером мультикаста для qt 4.7, очень большая просьба. Примеры из инета не работают, а в чём причина сложно разобраться.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.5.2011, 17:06
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(MedEx @ 20.5.2011, 11:22) *
Примеры из инета не работают
а например какие?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MedEx
  опции профиля:
сообщение 27.5.2011, 8:54
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 11.2.2011
Пользователь №: 2403

Спасибо сказали: 0 раз(а)




Репутация:   0  


Litkevich Yuriy,
извините за задержку, работой завалили.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#ifdef Q_OS_WIN
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QStringList items;

    foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())     //тут ошибки
        {
           if (interface.flags().testFlag(QNetworkInterface::IsRunning))                 //
           foreach (QNetworkAddressEntry entry, interface.addressEntries())        //
             {
                    if ( interface.hardwareAddress() != "00:00:00:00:00:00"
                         && entry.ip().toString().contains(".")
                         && entry.ip().toString()!="127.0.0.1")
                    items << entry.ip().toString();
             }
        }

    for(int i=0;i<items.size();i++)
    {
        QUdpSocket * MCastSocket = new QUdpSocket(this);

        MCastSocket->bind(QHostAddress(items[i]),9090,QUdpSocket::ReuseAddressHint);
        struct ip_mreq mcast;
        int opt = 1; // 0, если на собственный адрес отправлять не нужно
        int ttl = 1;
        int sd = MCastSocket->socketDescriptor();
        memset(&mcast, 0, sizeof(struct ip_mreq));
        mcast.imr_multiaddr.s_addr = inet_addr("224.0.0.221");
        mcast.imr_interface.s_addr = inet_addr((char *)items[i].toAscii().data_ptr());
        setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&opt, sizeof(int));
        setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl));
        setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mcast.imr_interface.s_addr, sizeof(mcast.imr_interface.s_addr));
        setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mcast, sizeof(mcast));

        if(MCastSocket->socketDescriptor()==-1)
        {
           delete MCastSocket;
           continue;
        }

        UdpSocketList << MCastSocket;
        connect(MCastSocket, SIGNAL(readyRead()),this, SLOT(RecvDatagrams()));
    }
}

In constructor 'MainWindow::MainWindow(QWidget*)':
error: expected primary-expression before 'struct'
error: expected ';' before 'struct'
error: expected primary-expression before 'struct'
...
16 сообщений.
Комментирую от "struct ip_mreq" по последнего сетсокопта...ошибки исчезают.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MedEx
  опции профиля:
сообщение 24.6.2011, 9:16
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 11.2.2011
Пользователь №: 2403

Спасибо сказали: 0 раз(а)




Репутация:   0  


если кому ещё интересен мультикаст
Цитата
foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())

видимо есть совпадение имён с файлами windows.h или iphlpapi.h
заменить на
Цитата
foreach(QNetworkInterface interface_x, QNetworkInterface::allInterfaces())
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.12.2024, 8:53