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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Биндинг сокетов на разные сетевые карты и LoopBack..  (Прочитано 6190 раз)
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.148 секунд. Запросов: 22.