Every newconnection, use a thread.
To modify your existing TCP server implementation in the MainWindow
class so that every new connection is handled in its own separate thread, you'll need to create a QThread
for each new connection. This can be achieved by creating a dedicated class to handle client connections and managing it within its thread.
Here's how you can do it:
1. Create ClientHandler Class
We'll create a ClientHandler
class that will handle the communication with the client. This class will inherit from QObject
, and it will utilize a QTcpSocket
for communication.
Header File: ClientHandler.h
cpp
#ifndef CLIENTHANDLER_H
#define CLIENTHANDLER_H
#include <QObject>
#include <QTcpSocket>
class ClientHandler : public QObject
{
Q_OBJECT
public:
explicit ClientHandler(qintptr socketDescriptor, QObject *parent = nullptr);
void process();
signals:
void disconnected();
private slots:
void onReadyRead();
void onDisconnected();
private:
QTcpSocket *clientSocket;
};
#endif // CLIENTHANDLER_H
cpp
Source File: ClientHandler.cpp
cpp
#include "ClientHandler.h"
#include <QDebug>
ClientHandler::ClientHandler(qintptr socketDescriptor, QObject *parent)
: QObject(parent)
{
clientSocket = new QTcpSocket(this);
if (clientSocket->setSocketDescriptor(socketDescriptor)) {
connect(clientSocket, &QTcpSocket::readyRead, this, &ClientHandler::onReadyRead);
connect(clientSocket, &QTcpSocket::disconnected, this, &ClientHandler::onDisconnected);
} else {
emit disconnected();
}
}
void ClientHandler::onReadyRead()
{
QByteArray data = clientSocket->readAll();
qDebug() << "Data received from client: " << data;
// Process data and send response
QString response = "Server received: " + QString::number(data.size()) + " bytes.";
clientSocket->write(response.toUtf8());
}
void ClientHandler::onDisconnected()
{
qDebug() << "Client disconnected.";
emit disconnected();
clientSocket->deleteLater();
}
cpp
2. Modify the MainWindow
Now we'll modify the MainWindow
class to use the ClientHandler
in a separate thread.
Main Window Implementation
Header File: MainWindow.h
Make sure to include the ClientHandler
header, and add the necessary includes for threading:
cpp
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>
#include <QLabel>
#include <QVBoxLayout>
#include <QList>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void onNewConnection();
private:
void setupUI();
QTcpServer *tcpServer;
QLabel *statusLabel;
QList<QTcpSocket*> clientSockets;
};
cpp
Source File: MainWindow.cpp
Here’s the updated implementation of the MainWindow
class to use threads for each new connection:
cpp
#include "mainwindow.h"
#include "ClientHandler.h"
#include <QThread>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), tcpServer(new QTcpServer(this))
{
setupUI();
// Start the TCP server on port 1234
if (!tcpServer->listen(QHostAddress::Any, 1234)) {
statusLabel->setText("Server failed to start.");
} else {
statusLabel->setText("Server listening on port 1234");
}
// Connect the newConnection signal from the server to the slot
connect(tcpServer, &QTcpServer::newConnection, this, &MainWindow::onNewConnection);
}
MainWindow::~MainWindow()
{
// Close all connections when shutting down
foreach(QTcpSocket* socket, clientSockets) {
if (socket) {
socket->close();
socket->deleteLater();
}
}
}
void MainWindow::setupUI()
{
QWidget *centralWidget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout;
statusLabel = new QLabel("Server not started", this);
layout->addWidget(statusLabel);
centralWidget->setLayout(layout);
setCentralWidget(centralWidget);
}
void MainWindow::onNewConnection()
{
// Accept new connection
QTcpSocket *clientSocket = tcpServer->nextPendingConnection();
// Use a new thread to handle this connection
QThread *thread = QThread::create([clientSocket]() {
ClientHandler handler(clientSocket->socketDescriptor());
handler.process(); // Call process in the thread
});
// Move the thread to the event loop and disconnect it on finish
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(clientSocket, &QTcpSocket::disconnected, thread, &QThread::quit);
// Start the thread
thread->start();
// Add the new socket to the list of connected clients
clientSockets.append(clientSocket);
statusLabel->setText("New client connected!");
}
cpp
Explanation
-
ClientHandler Class:
- Implements handling for the TCP connection, including reading data and handling disconnections.
- Managed by the
MainWindow
class throughQTcpSocket
.
-
MainWindow Class:
- On a new connection, creates a new
QThread
for the correspondingClientHandler
. - Ensures that when the socket is disconnected, the thread cleans itself up properly.
- On a new connection, creates a new
-
Thread Management:
- Each
ClientHandler
instance runs in its own thread, enabling simultaneous handling of multiple clients.
- Each
Note
Make sure you have the necessary QT += network
in your .pro
file to link against the Qt Network module. With these changes, every new client connection to your server will be handled on a separate thread, allowing your server to manage multiple clients concurrently.
原文地址:https://blog.csdn.net/m0_68739984/article/details/142463993
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!