福星服务器
演示如何创建网络服务器的示例。
它使用QTcpServer来接受传入的 TCP 连接,并使用基于简单QDataStream的数据传输协议将祝福写入连接的客户端(从福星客户端示例),然后关闭连接。
class Server : public QDialog { Q_OBJECT public: explicit Server(QWidget *parent = nullptr); private slots: void sendFortune(); private: void initServer(); QLabel *statusLabel = nullptr; QTcpServer *tcpServer = nullptr; QList<QString> fortunes; };
此服务器仅使用一个用于处理传入连接的槽的简单类实现。
tcpServer = new QTcpServer(this); if (!tcpServer->listen()) { QMessageBox::critical(this, tr("Fortune Server"), tr("Unable to start the server: %1.") .arg(tcpServer->errorString())); close(); return; } QString ipAddress; const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses(); // use the first non-localhost IPv4 address for (const QHostAddress &entry : ipAddressesList) { if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) { ipAddress = entry.toString(); break; } } // if we did not find one, use IPv4 localhost if (ipAddress.isEmpty()) ipAddress = QHostAddress(QHostAddress::LocalHost).toString(); statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n" "Run the Fortune Client example now.") .arg(ipAddress).arg(tcpServer->serverPort()));
在其构造函数中,我们的 Server 对象调用QTcpServer::listen()来设置一个侦听所有地址、任意端口的QTcpServer。然后它在标签中显示QTcpServer拾取的端口号,以便用户知道祝福客户端应连接到哪个端口号。
fortunes << tr("You've been leading a dog's life. Stay off the furniture.") << tr("You've got to think about tomorrow.") << tr("You will be surprised by a loud noise.") << tr("You will feel hungry again in another hour.") << tr("You might have mail.") << tr("You cannot kill time without injuring eternity.") << tr("Computers are not intelligent. They only think they are.");
我们的服务器生成一个可以发送给连接客户端的随机祝福列表。
connect(tcpServer, &QTcpServer::newConnection, this, &Server::sendFortune);
当客户端连接到我们的服务器时,QTcpServer将发出QTcpServer::newConnection()。反过来,这将调用我们的 sendFortune() 槽
void Server::sendFortune() { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_5); out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];
这个槽的目的是从我们的祝福列表中随机选择一行,使用QDataStream将其编码为QByteArray,然后将其写入连接的套接字。这是使用QTcpSocket传输二进制数据的一种常见方法。我们首先创建一个QByteArray和一个QDataStream对象,并将 bytearray 传递给QDataStream的构造函数。然后我们显式设置QDataStream的协议版本为QDataStream::Qt_5_10,以确保我们可以与来自 Qt 未来版本的客户端进行通信(见QDataStream::setVersion)(). 我们继续以随机祝福进行流式传输。
QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); connect(clientConnection, &QAbstractSocket::disconnected, clientConnection, &QObject::deleteLater);
然后我们调用QTcpServer::nextPendingConnection(),它返回表示连接服务器端的QTcpSocket。通过将QTcpSocket::disconnected()连接到QObject::deleteLater(),我们确保套接字在断开连接后将进行删除。
clientConnection->write(block); clientConnection->disconnectFromHost(); }
使用QTcpSocket::write()写入编码的祝福,我们最终调用QTcpSocket::disconnectFromHost(),这将关闭连接,在QTcpSocket将祝福写入网络后。因为QTcpSocket是异步工作的,所以在该函数返回后,数据将被写入,并返回控制权到 Qt 的事件循环。套接字随后将关闭,这会触发QObject::deleteLater()来删除它。
© 2024 Qt公司期权有限公司。本文件中包含的文档贡献由各自所有者拥有版权。本文件提供的文档是根据自由软件基金会发布的GNU自由文档许可协议版1.3的条款许可的。Qt及其相关标志是芬兰及其它国家和地区Qt公司有限责任公司的商标。所有其他商标均为其各自所有者的财产。