Sending messages from a client to server using network on the same machine
-
Yes, you're right. I partly changed all six files to match the requirements as follows:
The server part:
server.h
:class Server : public QObject { Q_OBJECT public: explicit Server(QObject *parent = nullptr); public slots: QString initServer(); void setMessage(); QString getMessage() const; void onNewConnection(); private: QTcpServer* tcpServer { nullptr }; QDataStream in; QString message; };
server.cpp
:Server::Server(QObject *parent) : QObject{parent} , tcpServer(new QTcpServer(this)) { initServer(); connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); } QString Server::initServer() { //.. Provide the IP address and port number for the client } void Server::onNewConnection() { QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); connect(clientConnection, &QAbstractSocket::disconnected, clientConnection, &QObject::deleteLater); in.setDevice(clientConnection); in.setVersion(QDataStream::Qt_4_0); connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::setMessage); } void Server::setMessage() { in.startTransaction(); QString msg; in >> msg; if (!in.commitTransaction()) message = "commitTransaction error" ; else message = msg; } QString Server::getMessage() const { return message; }
server's qml file
:ColumnLayout { anchors.fill: parent Label { text: myObj.initServer() } Label { id: msgLabel text: myObj.getMessage() } } ServerClass{ id: myObj }
The client part:
client.h
:class Client : public QObject { Q_OBJECT public: explicit Client(QObject *parent = nullptr); public slots: void sendAddress(QString, QString); void sendMessage(const QString&); private: QTcpSocket* tcpSocket { nullptr }; QDataStream out; };
client.cpp
:Client::Client(QObject *parent) : QObject{parent} , tcpSocket(new QTcpSocket(this)) { out.setDevice(tcpSocket); out.setVersion(QDataStream::Qt_4_0); } void Client::sendAddress(QString ip, QString port) { tcpSocket->abort(); tcpSocket->connectToHost(ip, port.toInt()); } void Client::sendMessage(const QString& message) { out.startTransaction(); out << message; if (!out.commitTransaction()) return ; }
client's qml file
:ColumnLayout { anchors.fill: parent TextField { id: ipAddrs } TextField { id: portNum } Button { text: "Send Address" onClicked: myObj.sendAddress(ipAddrs.text.toString(), portNum.text.toString()) } RowLayout { Layout.alignment: Qt.AlignBottom TextField { id: txtField Layout.fillWidth: true } Button { text: qsTr("Send") onClicked: myObj.sendMessage(txtField.text) } } } ClientClass{ id: myObj } }
After running both projects this way, and typing the IP address and port number (given by the server UI) on the client UI and writing a text message there I click on the Send button, but nothing is shown on the server UI.
I'm almost sure now the goal is closer but there're still a number of mistakes that need to be worked out.
-
Are you using the Fortune client and server examples as a base ?
If so, please take a look at the server side implementation, QDataStream is used there to write the data in a QByteArray that is then written in the socket. The transaction handling happens on the receiving end. -
Are you using the Fortune client and server examples as a base ?
If so, please take a look at the server side implementation, QDataStream is used there to write the data in a QByteArray that is then written in the socket. The transaction handling happens on the receiving end.Are you using the Fortune client and server examples as a base ?
Partly.
QDataStream is used there to write the data in a QByteArray that is then written in the socket.
I didn't know QString wouldn't work, but anyway, it's now changed to:
void Client::sendMessage(const QString& message) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_10); out << message; }
But still no change in the result! :|
The transaction handling happens on the receiving end.
Yes, it's implemented in the setMessage() slot.
-
Are you using the Fortune client and server examples as a base ?
Partly.
QDataStream is used there to write the data in a QByteArray that is then written in the socket.
I didn't know QString wouldn't work, but anyway, it's now changed to:
void Client::sendMessage(const QString& message) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_10); out << message; }
But still no change in the result! :|
The transaction handling happens on the receiving end.
Yes, it's implemented in the setMessage() slot.
@qcoderpro said in Sending messages from a client to server using network on the same machine:
But still no change in the result!
Because sendMessage does not send anything.
It only writes the message into a QByteArray.
You also need to send that QByteArray through the socket. -
@qcoderpro said in Sending messages from a client to server using network on the same machine:
But still no change in the result!
Because sendMessage does not send anything.
It only writes the message into a QByteArray.
You also need to send that QByteArray through the socket.@jsulm
Yeah, right, so I added this line at the end of the slot:
tcpSocket->write(block);
But I think there's an earlier problem. No connection arrives. I set a debug in theonNewConnection()
slot in the server app but nothing is printed although I put the IP and port in the client and click on the "Send Address" button! :| -
@jsulm
Yeah, right, so I added this line at the end of the slot:
tcpSocket->write(block);
But I think there's an earlier problem. No connection arrives. I set a debug in theonNewConnection()
slot in the server app but nothing is printed although I put the IP and port in the client and click on the "Send Address" button! :|@qcoderpro Then you should debug on the client side
-
@qcoderpro Then you should debug on the client side
The client's sendAddress slot sends the IP and port number as a string and int respectively, based on this version. So that connection is expected to be received in the server's NewConnection() slot, but it doesn't, I don't know why! :|
-
The client's sendAddress slot sends the IP and port number as a string and int respectively, based on this version. So that connection is expected to be received in the server's NewConnection() slot, but it doesn't, I don't know why! :|
@qcoderpro said in Sending messages from a client to server using network on the same machine:
sendAddress slot sends the IP and port number
It does not send anything, it just calls connectToHost. Did you check what happens on client side? Is https://doc.qt.io/qt-5/qabstractsocket.html#connected emitted? Is https://doc.qt.io/qt-5/qabstractsocket.html#errorOccurred signal emitted?
-
@qcoderpro said in Sending messages from a client to server using network on the same machine:
sendAddress slot sends the IP and port number
It does not send anything, it just calls connectToHost. Did you check what happens on client side? Is https://doc.qt.io/qt-5/qabstractsocket.html#connected emitted? Is https://doc.qt.io/qt-5/qabstractsocket.html#errorOccurred signal emitted?
I set this in the client's sendAddress slot:
connect(tcpSocket, &QAbstractSocket::connected, []() { qDebug() << "Connected to the host"; });
And it prints that message on Application Output window. So the connection is assumed to be established correctly without errors. Right?
-
I set this in the client's sendAddress slot:
connect(tcpSocket, &QAbstractSocket::connected, []() { qDebug() << "Connected to the host"; });
And it prints that message on Application Output window. So the connection is assumed to be established correctly without errors. Right?
-
@qcoderpro I'd suggest that you go back to the fortune example and debug what is happening on the client and server side until you have a good understanding. I found it very useful when I was figuring out how Qt did sockets.
Do you have any background with sockets at all? If not, I wonder if it would be worth having a play around with something like Python first to firm up the ideas. The official Python docs on sockets are very good.
-
@qcoderpro I'd suggest that you go back to the fortune example and debug what is happening on the client and server side until you have a good understanding. I found it very useful when I was figuring out how Qt did sockets.
Do you have any background with sockets at all? If not, I wonder if it would be worth having a play around with something like Python first to firm up the ideas. The official Python docs on sockets are very good.
@Bob64
The fortune client/server apps are different from (at least) that point of view that the server sends messages to the client by a button on the client. It's way different from mine.
Well, these two QML apps are considerably simple but I don't know why we (helpers and me) can't work it out and get them to work! :(