Russian Qt Forum
Апреля 20, 2025, 06:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Биндинг сокетов на разные сетевые карты и LoopBack..  (Прочитано 6415 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Августа 03, 2015, 15:48 »

Привет. Есть сервер и клиент на разных машинах. Между сервером и клиентом проложено несколько параллелных сетевых каналов (кабелей).
Это сделано для надёжности.
Задача: при обрыве свзязи по одному каналу переключиться на следующий сетевой интерфейс. Для этого я воспользовался функцией QTcpSocket::bind.
Все работает отлично. Но есть один странный глюк.
Проще привести код, что бы объяснить.
Код:
void     CArmClient::connectToServer()
{
    switch (state()) {
    case    QAbstractSocket::UnconnectedState:
    //case    QAbstractSocket::BoundState:
    {
        fmustReconnect = true;

//проходимся по всем сетевым интерфейсам
        foreach (const QNetworkInterface & networkIface, QNetworkInterface::allInterfaces()) {

            qDebug("card %d:%s[%s]\tIsUp\t%d\tIsRunning\t%d",
                networkIface.index(),
                qPrintable(networkIface.humanReadableName()),
                qPrintable(networkIface.hardwareAddress()),
                networkIface.flags() & QNetworkInterface::IsUp?1:0,
                networkIface.flags() & QNetworkInterface::IsRunning?1:0);

//нужно выбрать следующий доступный и поднятый интерфейс (т.е. с активным линком)
            if(networkIface.isValid() && !(networkIface.flags() & QNetworkInterface::IsLoopBack) && (p_interface.hardwareAddress()!=networkIface.hardwareAddress()) && (networkIface.flags() & QNetworkInterface::IsUp) && !networkIface.addressEntries().isEmpty()) {
                //qDebug("try bind client to %s",qPrintable(networkIface.addressEntries().first().ip().toString()));
                if(!bind(networkIface.addressEntries().first().ip(),fconnectionConfig.port(),QAbstractSocket::ReuseAddressHint))
                    qDebug("Can't rebind client %s to network interface %s",qPrintable(fconnectionConfig.toString()),qPrintable(networkIface.humanReadableName()));
                else
                {
                    p_interface = networkIface;
                    emit    networkInterfaceChange();
                    qDebug("Client %s has been  rebound to %s",qPrintable(fconnectionConfig.toString()),qPrintable(networkIface.humanReadableName()));
                }
                break;
            }

        }

        connectToHost(fconnectionConfig.host(),fconnectionConfig.port());
    }
        break;
    default:
        break;
    }
}
Вобщем я прохожусь по всем QNetworkInterface, и нахожу тот, который активен (isUp). Проблема в том, что когда находится LoopBack интерфейс, на него биндится сокет, и почему то происходит коннект с сервером, хотя сервер на другой машине. Кто то может объяснить почему так? В коде я намеренно добавил условие !(networkIface.flags() & QNetworkInterface::IsLoopBack).
Т.е. без него выбирается LoopBack интерфейс после разрыва (т.к. он всегда активен), но связь с удаленным сервером все равно осуществляется, хотя я ожидал что связи не будет и по таймауту будет выбран другой сетевой интерфейс. Сейчас в машине стоит для отладки 3 сетевых, и два кабеля.
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #1 : Августа 04, 2015, 13:14 »

а почему бы сразу не забиндится на 0.0.0.0 ?
Записан
Archan_gel
Гость
« Ответ #2 : Августа 04, 2015, 17:54 »

а зачем изобритать велосипед. Почему сразу же не использовать Channel bonding (802.3ad)
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #3 : Августа 05, 2015, 10:44 »

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

Сообщений: 1177


Просмотр профиля
« Ответ #4 : Августа 05, 2015, 13:20 »

а если так: https://ru.wikipedia.org/wiki/Агрегирование_каналов ?
" ...  и повысить их надежность в случае отказа одного из каналов "

Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Марта 31, 2016, 12:04 »

Хороший совет, спасибо, думаю под линуксом заработает. А вот как быть с виндой?
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #6 : Марта 31, 2016, 12:05 »

Ещё вот словил глюк, что каналы, которые не подключены в текущий момент начинают жрать проц, в консоли пишется что попытка чтения в unconnected state.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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