Connections in Qt networking
-
wrote on 18 Apr 2022, 17:54 last edited by
Hi all,
If using the slot below in a client app we send the IP and port number:
void Client::sendAddress(QString ip, QString port) { tcpSocket->abort(); tcpSocket->connectToHost(ip, port.toInt()); }
to a sever app and:
connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
in the server app invokes the slotonNewConnection
with the following definition:void Server::onNewConnection() { QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); connect(clientConnection, &QAbstractSocket::errorOccurred, this, &Server::displayError); connect(clientConnection, &QAbstractSocket::disconnected, clientConnection, &QObject::deleteLater); in.setDevice(clientConnection); in.setVersion(QDataStream::Qt_4_0); connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage); }
When we once send the IP and port number to the server and the connection is that way established, we can send as many messages as we wish to, without sending the IP and port number another time. We can use QDataStream::Qt_6_3 for
in.setVersion(QDataStream::Qt_4_0);
rather than that version 4 but the important matter is that the other app ought to use the same version too. And theconnect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
will invoke the slot writeMessage when the QDataStreamin
notifies its device's socket (clientConnection) that a message has completely arrived from the sender and is now ready to read.
Right all, please? -
Hi,
You are not sending an address nor a port to the server, you establish a connection to it with said address and port.
QDataStream has no signal, if something emits readyRead, it's going to be the socket you created on the client side. On the server side, it's the socket that is created for you when the connection is established.
-
Hi,
You are not sending an address nor a port to the server, you establish a connection to it with said address and port.
QDataStream has no signal, if something emits readyRead, it's going to be the socket you created on the client side. On the server side, it's the socket that is created for you when the connection is established.
wrote on 18 Apr 2022, 19:43 last edited by qcoderpro@SGaist
Apparently it's the clientConnection socket in the last connect() that emits the signal readyRead. But how does it know a message has arrived from the client socket completely?And the second question is, is such a connection, established by the IP and port number from the client to server a one-way connection or two-way? I mean this way now we can send messages from client to server, but can we send messages back from server to client as well or does it need more code, please?
-
It does not know. That's up to you to establish a protocol to know when you have a full frame that is arrived. One protocol could be the use of QDataStream's transaction.
The connection established is bidirectional.
-
It does not know. That's up to you to establish a protocol to know when you have a full frame that is arrived. One protocol could be the use of QDataStream's transaction.
The connection established is bidirectional.
wrote on 18 Apr 2022, 20:11 last edited byThe writeMessage slot in the connection above is:
void Server::writeMessage() { in.startTransaction(); QString msg; in >> msg; if (!in.commitTransaction()) setMessage("commitTransaction error"); else setMessage(msg); }
So by
in.commitTransaction()
, when it return true, we make sure the message is completely arrived and then we can use it, right?The connection established is bidirectional.
This is the slot sendMessage from client to send the message using its socket.
void Client::sendMessage(const QString& message) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setDevice(tcpSocket); out.setVersion(QDataStream::Qt_5_10); out << message; tcpSocket->write(block); }
Can we write something similar to it in the server app to be able to send messages back to the client, and get the message there by a transaction like above, or is there an easier way, please?
-
The writeMessage slot in the connection above is:
void Server::writeMessage() { in.startTransaction(); QString msg; in >> msg; if (!in.commitTransaction()) setMessage("commitTransaction error"); else setMessage(msg); }
So by
in.commitTransaction()
, when it return true, we make sure the message is completely arrived and then we can use it, right?The connection established is bidirectional.
This is the slot sendMessage from client to send the message using its socket.
void Client::sendMessage(const QString& message) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setDevice(tcpSocket); out.setVersion(QDataStream::Qt_5_10); out << message; tcpSocket->write(block); }
Can we write something similar to it in the server app to be able to send messages back to the client, and get the message there by a transaction like above, or is there an easier way, please?
@qcoderpro said in Connections in Qt networking:
Can we write something similar to it in the server app to be able to send messages back to the client
Yes, you can.
"and get the message there by a transaction like above" - yes
-
@qcoderpro said in Connections in Qt networking:
Can we write something similar to it in the server app to be able to send messages back to the client
Yes, you can.
"and get the message there by a transaction like above" - yes
wrote on 19 Apr 2022, 19:46 last edited by@jsulm
Done! Thank you. :)One side question. As the two QML projects may to some extent look similar to Widgets Fortune client/server examples, these, too, work on the same machine properly. But when I install the server app on a virtual Android device and the client app on the PC and run both, they can't connect together and no messages are exchanged! While we use the exact IP and port the server exposes why can't the client connect to it like when they both are running on the same machine, please?
-
@jsulm
Done! Thank you. :)One side question. As the two QML projects may to some extent look similar to Widgets Fortune client/server examples, these, too, work on the same machine properly. But when I install the server app on a virtual Android device and the client app on the PC and run both, they can't connect together and no messages are exchanged! While we use the exact IP and port the server exposes why can't the client connect to it like when they both are running on the same machine, please?
@qcoderpro My guess is that on Android you can't easilly run a server exposing a port to clients. You probably will need to request additional rights for your server running on Android.
-
@qcoderpro My guess is that on Android you can't easilly run a server exposing a port to clients. You probably will need to request additional rights for your server running on Android.
wrote on 20 Apr 2022, 07:05 last edited byOne of my goals for developing the projects in QML was to use them on mobile devices, say, Android. Suppose someone installs the server app on their Android device and another, somewhere else, installs the client app on their Android device. The one running the client app will somehow be aware of the IP and port number exposed by server. They should then be able to exchange messages in a way. How to do that? How do you guide me to reach this goal, please?
1/9