Russian Qt Forum

Qt => Работа с сетью => Тема начата: Fregloin от Август 03, 2015, 15:48



Название: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: Fregloin от Август 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 сетевых, и два кабеля.


Название: Re: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: qate от Август 04, 2015, 13:14
а почему бы сразу не забиндится на 0.0.0.0 ?


Название: Re: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: Archan_gel от Август 04, 2015, 17:54
а зачем изобритать велосипед. Почему сразу же не использовать Channel bonding (802.3ad)


Название: Re: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: Fregloin от Август 05, 2015, 10:44
мне не нужно повышать пропускную способность, мне нужно реализовать гарячее резервирование по двум каналам. т.е. если загинается один свич или теряется связь по одному каналу, должен происходить переход на второй канал. каналы - две разные физические сети проложенные параллельно, но питающиеся от разных источников.


Название: Re: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: qate от Август 05, 2015, 13:20
а если так: https://ru.wikipedia.org/wiki/Агрегирование_каналов ?
" ...  и повысить их надежность в случае отказа одного из каналов "



Название: Re: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: Fregloin от Март 31, 2016, 12:04
Хороший совет, спасибо, думаю под линуксом заработает. А вот как быть с виндой?


Название: Re: Биндинг сокетов на разные сетевые карты и LoopBack..
Отправлено: Fregloin от Март 31, 2016, 12:05
Ещё вот словил глюк, что каналы, которые не подключены в текущий момент начинают жрать проц, в консоли пишется что попытка чтения в unconnected state.