Russian Qt Forum

Qt => Работа с сетью => Тема начата: Dimas от Декабрь 01, 2011, 12:53



Название: Bind в QTcpSocket
Отправлено: Dimas от Декабрь 01, 2011, 12:53
Есть клиент с двумя сетевыми интерфейсами и сервер.
Работаю над клиентом.Клиент должен обмениваться с сервером по двум линиям для резервирования линий. В windows api я привязывал сокет к определенному ip и все работало. В QT 4.5 я не нашел такой функции.
Есть функция


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


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

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

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


Название: Re: Bind в QTcpSocket
Отправлено: LisandreL от Декабрь 01, 2011, 13:56
2 QTcpServer'а, в QTcpServer::listen указывайте нужный интерфейсы (а не QHostAddress::Any).
Интерфейсы можно получить через QNetworkInterface::allAddresses() или QNetworkInterface::allInterfaces().


Название: Re: Bind в QTcpSocket
Отправлено: Dimas от Декабрь 01, 2011, 14:02
Меня интересует привязка сокетов к ip адресу на стороне клиента.

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

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

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


Название: Re: Bind в QTcpSocket
Отправлено: Dimas от Декабрь 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 (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.


Название: Re: Bind в QTcpSocket
Отправлено: LisandreL от Декабрь 14, 2011, 23:43
До прихода пятёрки можно использовать нативный bind (для всех необходимых вам ОС).
Благо дескриптор сокета доступен через socketDescriptor.
Code Less. Create More. #ifdef Everywhere


Название: Re: Bind в QTcpSocket
Отправлено: Dimas от Декабрь 15, 2011, 08:27
Я пробовал получать дескриптор сокета для вызова api функции bind. Не получилось. Дескриптор сокета можно получить только после выполнения коннекта. До этого возвращает -1.


Название: Re: Bind в QTcpSocket
Отправлено: Akon от Декабрь 16, 2011, 09:30
Сталкивался с проблемой. QTcpSocket не создает системного сокета до реальной необходимости (т.е. до коннекта). Создавайте системный сокет, биндите его к нужному сетевому интерфейсу, коннектите его и подпихивайте в QTcpSocket (setSocketDescriptor). Не помню - но коннектить можно уже через QTcpSocket.


Название: Re: Bind в QTcpSocket
Отправлено: Dimas от Декабрь 16, 2011, 09:31
Можно по подробнее про системный сокет.


Название: Re: Bind в QTcpSocket
Отправлено: Akon от Декабрь 16, 2011, 11:10
SOCKET s = АПИ, создающая сокет
bind(s, желаемый сетевой интерфейс);
QTcpSocket qs;
ds.setSocketDescriptor(s);
ds.connectToHost(...);


Название: Re: Bind в QTcpSocket
Отправлено: Dimas от Декабрь 16, 2011, 11:36
Спасибо, попробую