qt tcp 服务器多线程与多个客户端通信
时间: 2023-08-10 11:09:36 浏览: 170
Qt多线程TCP服务器
在Qt中,可以通过QTcpServer类来实现TCP服务器的编写,而多线程则可以通过QThread类来实现。下面是一个简单的示例程序,可以实现多线程与多个客户端的通信:
```cpp
#include <QtNetwork>
#include <QtWidgets>
#include <QtCore>
class ClientThread : public QThread
{
Q_OBJECT
public:
explicit ClientThread(qintptr socketDescriptor, QObject *parent = nullptr)
: QThread(parent), m_socketDescriptor(socketDescriptor)
{
}
signals:
void error(QTcpSocket::SocketError socketError);
protected:
void run() override
{
QTcpSocket socket;
if (!socket.setSocketDescriptor(m_socketDescriptor)) {
emit error(socket.error());
return;
}
connect(&socket, &QTcpSocket::readyRead, this, &ClientThread::readyRead);
connect(&socket, &QTcpSocket::disconnected, this, &ClientThread::disconnected);
exec();
}
private slots:
void readyRead()
{
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
if (!socket)
return;
QByteArray data = socket->readAll();
// 处理接收到的数据
socket->flush();
}
void disconnected()
{
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
if (!socket)
return;
socket->deleteLater();
quit();
}
private:
qintptr m_socketDescriptor;
};
class TcpServer : public QTcpServer
{
Q_OBJECT
public:
TcpServer(QObject *parent = nullptr)
: QTcpServer(parent)
{
}
protected:
void incomingConnection(qintptr socketDescriptor) override
{
ClientThread *thread = new ClientThread(socketDescriptor, this);
connect(thread, &ClientThread::finished, thread, &ClientThread::deleteLater);
thread->start();
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
TcpServer server;
if (!server.listen(QHostAddress::Any, 1234)) {
qCritical() << "Failed to start server:" << server.errorString();
return 1;
}
qDebug() << "Server started:" << server.serverAddress().toString() << server.serverPort();
return app.exec();
}
#include "main.moc"
```
在这个示例程序中,TcpServer类继承自QTcpServer类,其中的incomingConnection()函数会在新的客户端连接时被调用。在该函数中,我们创建一个新的ClientThread线程,并将客户端的socket描述符传递给它。在ClientThread线程中,我们可以通过QTcpSocket类来与客户端进行通信。当客户端连接断开时,我们需要清理socket并退出线程。
需要注意的是,由于Qt的对象树模型,我们需要在ClientThread线程中使用deleteLater()函数来删除socket对象。这可以确保socket对象不会在其所属的线程销毁之前被销毁。
阅读全文