How can the server process different requests from different clients?
-
Hi all. I have a client/server application that accepts a message from one client and broadcasts it to everyone. But what should I do if I want to add functionality? Let's say - authorization, or replenishment of the wallet, etc. How in this case to teach to understand the server, what to return to a specific user. Tell me which way to dig
Here is the code:
Server:Server::Server() { if (listen(QHostAddress::Any, 2323)) { qDebug() << "start"; } else { qDebug() << "error"; } next_block_size_ = 0; } void Server::SendToClient(QString str) { data_.clear(); QDataStream out(&data_, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_2); out << quint16(0) << str; out.device()->seek(0); out.device()->seek(data_.size() - sizeof(quint16)); for (int i = 0; i < Sockets.size(); ++i) { auto socket = QPointer<QTcpSocket>(Sockets.at(i)); if (socket) { socket->write(data_); } else { Sockets.removeOne(socket); } } } void Server::incomingConnection(qintptr socketDescriptor) { qDebug() << "hello"; socket = new QTcpSocket; socket->setSocketDescriptor(socketDescriptor); connect(socket, &QTcpSocket::readyRead, this, &Server::slotReadyRead); connect(socket, &QTcpSocket::disconnected, this, &Server::Disconnect); Sockets.push_back(socket); qDebug() << "client connected" << socketDescriptor; } void Server::slotReadyRead() { socket = (QTcpSocket*)sender(); QDataStream in(socket); in.setVersion(QDataStream::Qt_6_2); if (in.status() == QDataStream::Ok) { qDebug() << "read ..."; while(1) { if (next_block_size_ == 0) { if (socket->bytesAvailable() < 2) { break; } in >> next_block_size_; } if (socket->bytesAvailable() < next_block_size_) { break; } QString str; in >> str; next_block_size_ = 0; SendToClient(str); break; } } else { qDebug() << "Error DataStream"; } } void Server::Disconnect() { auto socket = qobject_cast<QTcpSocket*>(sender()); if (socket) { Sockets.removeOne(socket); socket->deleteLater(); } }Client:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); socket = nullptr; connect(ui->ConnectToServer, SIGNAL(released()), this, SLOT(Connect())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::Connect() { if (socket == nullptr) { socket = new QTcpSocket(this); connect(socket, &QTcpSocket::readyRead, this, &MainWindow::slotReadyRead); connect(socket, &QTcpSocket::disconnected, this, &MainWindow::Disconnect); qDebug() << "press connect"; next_block_size_ = 0; socket->connectToHost("127.0.0.1", 2323); if(!socket->waitForConnected(5000)) { qDebug() << "Error: " << socket->errorString(); delete socket; socket = nullptr; } } } void MainWindow::Disconnect() { socket->deleteLater(); socket = nullptr; } void MainWindow::SendToServer(QString str) { if (socket != nullptr) { data_.clear(); QDataStream out(&data_, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_2); out << quint16(0) << str; out.device()->seek(0); out.device()->seek(data_.size() - sizeof(quint16)); socket->write(data_); ui->lineEdit->clear(); } } void MainWindow::slotReadyRead() { QDataStream in (socket); in.setVersion(QDataStream::Qt_6_2); if (in.status() == QDataStream::Ok) { while(1) { if (next_block_size_ == 0) { if (socket->bytesAvailable() < 2) { break; } in >> next_block_size_; } if (socket->bytesAvailable() < next_block_size_) { break; } QString str; in >> str; next_block_size_ = 0; ui->textBrowser->append(str); } } else { ui->textBrowser->append("Error read"); } } void MainWindow::on_pushButton_2_clicked() { SendToServer(ui->lineEdit->text()); } void MainWindow::on_lineEdit_returnPressed() { SendToServer(ui->lineEdit->text()); }I will then connect the last slots via connect
-
Hi all. I have a client/server application that accepts a message from one client and broadcasts it to everyone. But what should I do if I want to add functionality? Let's say - authorization, or replenishment of the wallet, etc. How in this case to teach to understand the server, what to return to a specific user. Tell me which way to dig
Here is the code:
Server:Server::Server() { if (listen(QHostAddress::Any, 2323)) { qDebug() << "start"; } else { qDebug() << "error"; } next_block_size_ = 0; } void Server::SendToClient(QString str) { data_.clear(); QDataStream out(&data_, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_2); out << quint16(0) << str; out.device()->seek(0); out.device()->seek(data_.size() - sizeof(quint16)); for (int i = 0; i < Sockets.size(); ++i) { auto socket = QPointer<QTcpSocket>(Sockets.at(i)); if (socket) { socket->write(data_); } else { Sockets.removeOne(socket); } } } void Server::incomingConnection(qintptr socketDescriptor) { qDebug() << "hello"; socket = new QTcpSocket; socket->setSocketDescriptor(socketDescriptor); connect(socket, &QTcpSocket::readyRead, this, &Server::slotReadyRead); connect(socket, &QTcpSocket::disconnected, this, &Server::Disconnect); Sockets.push_back(socket); qDebug() << "client connected" << socketDescriptor; } void Server::slotReadyRead() { socket = (QTcpSocket*)sender(); QDataStream in(socket); in.setVersion(QDataStream::Qt_6_2); if (in.status() == QDataStream::Ok) { qDebug() << "read ..."; while(1) { if (next_block_size_ == 0) { if (socket->bytesAvailable() < 2) { break; } in >> next_block_size_; } if (socket->bytesAvailable() < next_block_size_) { break; } QString str; in >> str; next_block_size_ = 0; SendToClient(str); break; } } else { qDebug() << "Error DataStream"; } } void Server::Disconnect() { auto socket = qobject_cast<QTcpSocket*>(sender()); if (socket) { Sockets.removeOne(socket); socket->deleteLater(); } }Client:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); socket = nullptr; connect(ui->ConnectToServer, SIGNAL(released()), this, SLOT(Connect())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::Connect() { if (socket == nullptr) { socket = new QTcpSocket(this); connect(socket, &QTcpSocket::readyRead, this, &MainWindow::slotReadyRead); connect(socket, &QTcpSocket::disconnected, this, &MainWindow::Disconnect); qDebug() << "press connect"; next_block_size_ = 0; socket->connectToHost("127.0.0.1", 2323); if(!socket->waitForConnected(5000)) { qDebug() << "Error: " << socket->errorString(); delete socket; socket = nullptr; } } } void MainWindow::Disconnect() { socket->deleteLater(); socket = nullptr; } void MainWindow::SendToServer(QString str) { if (socket != nullptr) { data_.clear(); QDataStream out(&data_, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_2); out << quint16(0) << str; out.device()->seek(0); out.device()->seek(data_.size() - sizeof(quint16)); socket->write(data_); ui->lineEdit->clear(); } } void MainWindow::slotReadyRead() { QDataStream in (socket); in.setVersion(QDataStream::Qt_6_2); if (in.status() == QDataStream::Ok) { while(1) { if (next_block_size_ == 0) { if (socket->bytesAvailable() < 2) { break; } in >> next_block_size_; } if (socket->bytesAvailable() < next_block_size_) { break; } QString str; in >> str; next_block_size_ = 0; ui->textBrowser->append(str); } } else { ui->textBrowser->append("Error read"); } } void MainWindow::on_pushButton_2_clicked() { SendToServer(ui->lineEdit->text()); } void MainWindow::on_lineEdit_returnPressed() { SendToServer(ui->lineEdit->text()); }I will then connect the last slots via connect
@Idodoqdo said in How can the server process different requests from different clients?:
How in this case to teach to understand the server, what to return to a specific user.
What do you mean by this? Only you know what the server returns to you, or what your clients send to the server and how you want it to act on such "messages"?
-
@JonB said in How can the server process different requests from different clients?:
What do you mean by this? Only you know what the server returns to you, or what your clients send to the server and how you want it to act on such "messages"?
this - what your clients send to the server and how you want it to act on such "messages"?
Processing by the server of requests from the client. Requests may vary. -
@JonB said in How can the server process different requests from different clients?:
What do you mean by this? Only you know what the server returns to you, or what your clients send to the server and how you want it to act on such "messages"?
this - what your clients send to the server and how you want it to act on such "messages"?
Processing by the server of requests from the client. Requests may vary.@Idodoqdo
Not sure what your actual question is then? You have to write whatever code you want at both sides to pass and act on "messages". You define some "protocol" for that: what the messages are, how they are sent, how the server/client reacts to them, etc. There is not some existing code or protocol for this,QTcp...just sends/receives arbitrary streams of bytes, you have to write whatever code to impose some "meaning" on these. -
@Idodoqdo
Not sure what your actual question is then? You have to write whatever code you want at both sides to pass and act on "messages". You define some "protocol" for that: what the messages are, how they are sent, how the server/client reacts to them, etc. There is not some existing code or protocol for this,QTcp...just sends/receives arbitrary streams of bytes, you have to write whatever code to impose some "meaning" on these. -
@JonB I do not understand how to transfer a specific user to a specific stage. One authorizes, the other submits the application. What tool to use? Pass a structure that has one of the parameters - the action cipher? Or json?
@Idodoqdo
Again, I do not understand your question or what you are expecting as an answer. You can pass whatever you like between client and server. You can pass it as JSON, some kind of structure, text, whatever your client & server agree to exchange. Nobody knows what is appropriate from your question/description, nobody knows what "authorization" you are talking about, nobody knows what "tool" you might be thinking of, nobody knows what structure/JSON/"action cipher" you are mentioning..... -
@Idodoqdo
Again, I do not understand your question or what you are expecting as an answer. You can pass whatever you like between client and server. You can pass it as JSON, some kind of structure, text, whatever your client & server agree to exchange. Nobody knows what is appropriate from your question/description, nobody knows what "authorization" you are talking about, nobody knows what "tool" you might be thinking of, nobody knows what structure/JSON/"action cipher" you are mentioning.....void Server::slotReadyRead() { socket = (QTcpSocket*)sender(); QDataStream in(socket); in.setVersion(QDataStream::Qt_6_2); if (in.status() == QDataStream::Ok) { qDebug() << "read ..."; while(1) { if (next_block_size_ == 0) { if (socket->bytesAvailable() < 2) { break; } in >> next_block_size_; } if (socket->bytesAvailable() < next_block_size_) { break; } QString str; in >> str; next_block_size_ = 0; SendToClient(str); break; } } else { qDebug() << "Error DataStream"; } }here I am reading data into a QString and always doing the SendToClient(QString str) method, but what if I want to do different things depending on the message that came through. Do I need to use an if- construct? How will I understand what the client now wants from the server? Do I need to specify some kind of cipher for this action? for example pseudocode:
QString str; // what other data type, let's say QStruct in >> str; next_block_size_ = 0; if (str == "hello") { // there may be a key pointing to a method GoToAuthorization(str); } else if (str == 'buy') { CreateApplication(str); } -
void Server::slotReadyRead() { socket = (QTcpSocket*)sender(); QDataStream in(socket); in.setVersion(QDataStream::Qt_6_2); if (in.status() == QDataStream::Ok) { qDebug() << "read ..."; while(1) { if (next_block_size_ == 0) { if (socket->bytesAvailable() < 2) { break; } in >> next_block_size_; } if (socket->bytesAvailable() < next_block_size_) { break; } QString str; in >> str; next_block_size_ = 0; SendToClient(str); break; } } else { qDebug() << "Error DataStream"; } }here I am reading data into a QString and always doing the SendToClient(QString str) method, but what if I want to do different things depending on the message that came through. Do I need to use an if- construct? How will I understand what the client now wants from the server? Do I need to specify some kind of cipher for this action? for example pseudocode:
QString str; // what other data type, let's say QStruct in >> str; next_block_size_ = 0; if (str == "hello") { // there may be a key pointing to a method GoToAuthorization(str); } else if (str == 'buy') { CreateApplication(str); }@Idodoqdo said in How can the server process different requests from different clients?:
I need to use an if- construct?
Of course, yes, in some shape of form! You have to write code to do whatever it is you want to do, it is not just going to "happen".
How will I understand what the client now wants from the server?
I have tried to answer this several times. We don't know. You have to define some "protocol" where messages sent from client to server or server to client have to have some "meaning". And write the code to "parse" these messages and act on them. You have to choose what data, and in what form, you want to send/receive.
All you show so far is server code which expects the client to send a 2-byte count followed by that many bytes of further data. That's it. Nothing about what the data is or means or what to do with it. For example, and this is only an example, perhaps your 2-byte count might be preceded by a single byte whose value says what this message is about. You look at that first, and decide what to do at the server side appropriately. Or, maybe your "message type byte" is the very first byte in the data sent after the 2 byte count. Or, maybe you don't need/want to put "message types" into the messages, maybe your "protocol" states that the first "message" after initial connection will be a username or password and you deal with that first (only) message correspondingly.
I don't think I have anything further useful to say, I have said you just need to write the code you want for your message exchange.
-
@Idodoqdo said in How can the server process different requests from different clients?:
I need to use an if- construct?
Of course, yes, in some shape of form! You have to write code to do whatever it is you want to do, it is not just going to "happen".
How will I understand what the client now wants from the server?
I have tried to answer this several times. We don't know. You have to define some "protocol" where messages sent from client to server or server to client have to have some "meaning". And write the code to "parse" these messages and act on them. You have to choose what data, and in what form, you want to send/receive.
All you show so far is server code which expects the client to send a 2-byte count followed by that many bytes of further data. That's it. Nothing about what the data is or means or what to do with it. For example, and this is only an example, perhaps your 2-byte count might be preceded by a single byte whose value says what this message is about. You look at that first, and decide what to do at the server side appropriately. Or, maybe your "message type byte" is the very first byte in the data sent after the 2 byte count. Or, maybe you don't need/want to put "message types" into the messages, maybe your "protocol" states that the first "message" after initial connection will be a username or password and you deal with that first (only) message correspondingly.
I don't think I have anything further useful to say, I have said you just need to write the code you want for your message exchange.
-
Hi,
Before going further, you should take a step back. Authorization and wallet replenishment sounds like you will also need proper user management and cryptography as well a lot of other pieces.
I would recommend writing down the exact requirements you will have. There are lots of web solutions already existing (even using Qt like Cutelyst) that you should first check. Implementing everything from scratch in that field can be quite dangerous especially when user data is involved.
-
Hi,
Before going further, you should take a step back. Authorization and wallet replenishment sounds like you will also need proper user management and cryptography as well a lot of other pieces.
I would recommend writing down the exact requirements you will have. There are lots of web solutions already existing (even using Qt like Cutelyst) that you should first check. Implementing everything from scratch in that field can be quite dangerous especially when user data is involved.