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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Bind в QTcpSocket  (Прочитано 10739 раз)
Dimas
Чайник
*
Offline Offline

Сообщений: 50



Просмотр профиля
« : Декабрь 01, 2011, 12:53 »

Есть клиент с двумя сетевыми интерфейсами и сервер.
Работаю над клиентом.Клиент должен обмениваться с сервером по двум линиям для резервирования линий. В windows api я привязывал сокет к определенному ip и все работало. В QT 4.5 я не нашел такой функции.
Есть функция


Код:
    void setLocalAddress(const QHostAddress &address);


Но, в описании сказано:
"Вы можете вызвать эту функцию в подклассе QAbstractSocket, чтобы изменить возвращаемое значение localAddress () функция после того, как соединение было установлено...

Отметьте, что эта функция не связывает локальный адрес сокета до соединения (например, QUdpSocket:: bind())."
К тому же она protected.

Как привязать сокет к определенному IP адресу в QT?
Записан

qt 4.8.6, qt 5.12.4
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Декабрь 01, 2011, 13:56 »

2 QTcpServer'а, в QTcpServer::listen указывайте нужный интерфейсы (а не QHostAddress::Any).
Интерфейсы можно получить через QNetworkInterface::allAddresses() или QNetworkInterface::allInterfaces().
Записан
Dimas
Чайник
*
Offline Offline

Сообщений: 50



Просмотр профиля
« Ответ #2 : Декабрь 01, 2011, 14:02 »

Меня интересует привязка сокетов к ip адресу на стороне клиента.

Есть две сетевые карты ip1 и ip2.
Есть сервер на другой машине.

Клиент коннектиться к серверу с ip1. Это работает, идет обмен данными.
Запускаю второго клиента на этой же машине он должен создать сокет на ip2, для этого обычно используют bind, что позволяет зафиксировать сокет клиента на определенном сетевом интерфейсе.

Если не делать привязку оба сокета клиента будут коннектиться к серверу с сетевого интерфейса ip1, соответственно резервная линия не будет использоваться. Задача такая: программа клиент имеет две сетевые карты и должна вести обмен данными с сервером. Идет обмен данными по двум линиям одновременно и при физической порчи одной из линий обмен данными не нарушается.
Записан

qt 4.8.6, qt 5.12.4
Dimas
Чайник
*
Offline Offline

Сообщений: 50



Просмотр профиля
« Ответ #3 : Декабрь 14, 2011, 21:43 »

Функция bind для TCP появиться в Qt 5.0

bool QAbstractSocket::bind ( const QHostAddress & address, quint16 port = 0, BindMode mode = DefaultForPlatform )


http://doc.qt.nokia.com/5.0-snapshot/qabstractsocket.html#bind

Цитировать
Binds to address on port port, using the BindMode mode.
Binds this socket to the address address and the port port.
For UDP sockets, after binding, the signal QUdpSocket::readyRead() is emitted whenever a UDP datagram arrives on the specified address and port. Thus, This function is useful to write UDP servers.
For TCP sockets, this function may be used to specify which interface to use for an outgoing connection, which is useful in case of multiple network interfaces.
By default, the socket is bound using the DefaultForPlatform BindMode. If a port is not specified, a random port is chosen.
On success, the functions returns true and the socket enters BoundState; otherwise it returns false.
This function was introduced in Qt 5.0.

Примерный перевод:
Цитировать
...
Связывает этот сокет с ip адресом и портом.
...
Для сокетов TCP эта функция может использоваться, чтобы определить, какой интерфейс использовать для исходящего соединения, которое полезно в случае нескольких сетевых интерфейсов.
По умолчанию сокет связан, используя DefaultForPlatform BindMode. Если порт не определен, случайный порт выбран.
При успехе функции возвращают true, и сокет вводит BoundState; иначе это возвращает false.
Эта функция будет введена в Qt 5.0.
Записан

qt 4.8.6, qt 5.12.4
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #4 : Декабрь 14, 2011, 23:43 »

До прихода пятёрки можно использовать нативный bind (для всех необходимых вам ОС).
Благо дескриптор сокета доступен через socketDescriptor.
Code Less. Create More. #ifdef Everywhere
Записан
Dimas
Чайник
*
Offline Offline

Сообщений: 50



Просмотр профиля
« Ответ #5 : Декабрь 15, 2011, 08:27 »

Я пробовал получать дескриптор сокета для вызова api функции bind. Не получилось. Дескриптор сокета можно получить только после выполнения коннекта. До этого возвращает -1.
Записан

qt 4.8.6, qt 5.12.4
Akon
Гость
« Ответ #6 : Декабрь 16, 2011, 09:30 »

Сталкивался с проблемой. QTcpSocket не создает системного сокета до реальной необходимости (т.е. до коннекта). Создавайте системный сокет, биндите его к нужному сетевому интерфейсу, коннектите его и подпихивайте в QTcpSocket (setSocketDescriptor). Не помню - но коннектить можно уже через QTcpSocket.
Записан
Dimas
Чайник
*
Offline Offline

Сообщений: 50



Просмотр профиля
« Ответ #7 : Декабрь 16, 2011, 09:31 »

Можно по подробнее про системный сокет.
Записан

qt 4.8.6, qt 5.12.4
Akon
Гость
« Ответ #8 : Декабрь 16, 2011, 11:10 »

SOCKET s = АПИ, создающая сокет
bind(s, желаемый сетевой интерфейс);
QTcpSocket qs;
ds.setSocketDescriptor(s);
ds.connectToHost(...);
Записан
Dimas
Чайник
*
Offline Offline

Сообщений: 50



Просмотр профиля
« Ответ #9 : Декабрь 16, 2011, 11:36 »

Спасибо, попробую
Записан

qt 4.8.6, qt 5.12.4
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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