在 Qt 5.9.9 的 C++ 开发中,利用 QTcpSocket 时,要判断是服务端主动断开 TCP Socket 连接,可以通过处置惩罚 QTcpSocket 的 disconnected 信号,结合 QTcpSocket 的状态以及相干事件信息来综合判断。以下是具体的实现思绪和示例代码:
实现思绪
- 监听 disconnected 信号:当连接断开时,QTcpSocket 会发出 disconnected 信号,我们可以在槽函数中处置惩罚该信号。
- 检查连接状态:在 disconnected 信号的槽函数中,检查 QTcpSocket 的状态,判断是否为主动断开。可以结合网络错误码、服务端发送的特定消息等举行判断。
- 服务端主动断开的特征判断:例如,如果服务端在断开连接前发送了特定的关闭消息,客户端吸收到该消息后就可以知道是服务端主动断开;或者通过网络错误码判断是否是服务端正常关闭连接。
示例代码
- #include <QtNetwork/QTcpSocket>
- #include <QDebug>
- #include <QCoreApplication>
- class MyTcpClient : public QObject
- {
- Q_OBJECT
- public:
- MyTcpClient(QObject *parent = nullptr) : QObject(parent)
- {
- socket = new QTcpSocket(this);
- connect(socket, &QTcpSocket::disconnected, this, &MyTcpClient::onDisconnected);
- connect(socket, &QTcpSocket::readyRead, this, &MyTcpClient::onReadyRead);
- // 连接到服务端
- socket->connectToHost("127.0.0.1", 12345);
- }
- private slots:
- void onDisconnected()
- {
- // 检查是否是服务端主动断开
- if (socket->state() == QAbstractSocket::UnconnectedState) {
- // 可以进一步根据错误码判断
- if (socket->error() == QAbstractSocket::RemoteHostClosedError) {
- qDebug() << "Server主动断开连接";
- } else {
- qDebug() << "连接断开,错误码:" << socket->errorString();
- }
- }
- }
- void onReadyRead()
- {
- QByteArray data = socket->readAll();
- // 假设服务端发送 "CLOSE_CONNECTION" 表示主动断开连接
- if (data == "CLOSE_CONNECTION") {
- qDebug() << "收到服务端断开连接消息,即将断开连接";
- socket->disconnectFromHost();
- }
- }
- private:
- QTcpSocket *socket;
- };
- #include "main.moc"
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- MyTcpClient client;
- return a.exec();
- }
复制代码- #include <QtNetwork/QTcpServer>
- #include <QtNetwork/QTcpSocket>
- #include <QDebug>
- #include <QCoreApplication>
- class MyServer : public QTcpServer
- {
- Q_OBJECT
- public:
- explicit MyServer(QObject *parent = nullptr) : QTcpServer(parent) {}
- protected:
- void incomingConnection(qintptr socketDescriptor) override
- {
- QTcpSocket *socket = new QTcpSocket(this);
- if (!socket->setSocketDescriptor(socketDescriptor)) {
- qDebug() << "Failed to set socket descriptor.";
- delete socket;
- return;
- }
- connect(socket, &QTcpSocket::readyRead, this, [socket]() {
- QByteArray data = socket->readAll();
- qDebug() << "Received from client:" << data;
- // 将收到的数据原样返回给客户端
- socket->write(data);
- });
- connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
- }
- };
- #include "server.moc"
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- MyServer server;
- if (!server.listen(QHostAddress::Any, 12345)) {
- qDebug() << "Server could not start!";
- } else {
- qDebug() << "Server started!";
- }
- return a.exec();
- }
复制代码- #include <QtNetwork/QTcpSocket>
- #include <QDebug>
- #include <QCoreApplication>
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- QTcpSocket socket;
- socket.connectToHost(QHostAddress::LocalHost, 12345);
- if (socket.waitForConnected()) {
- qDebug() << "Connected to server!";
- // 向服务器发送消息
- socket.write("Hello, server!");
- socket.waitForBytesWritten();
- if (socket.waitForReadyRead()) {
- QByteArray data = socket.readAll();
- qDebug() << "Received from server:" << data;
- }
- } else {
- qDebug() << "Connection failed!";
- }
- socket.disconnectFromHost();
- if (socket.state() != QAbstractSocket::UnconnectedState) {
- socket.waitForDisconnected();
- }
- return a.exec();
- }
复制代码 代码解释
- MyTcpClient 类:继承自 QObject,封装了 QTcpSocket 对象,用于处置惩罚与服务端的连接。
- 构造函数:创建 QTcpSocket 对象,并连接 disconnected 和 readyRead 信号到相应的槽函数。然后尝试连接到服务端。
- onDisconnected 槽函数:在连接断开时被调用,检查 QTcpSocket 的状态和错误码。如果错误码为 QAbstractSocket::RemoteHostClosedError,则表示服务端主动断开连接。
- onReadyRead 槽函数:在有数据可读时被调用,检查服务端发送的数据。如果收到特定的关闭消息(如 “CLOSE_CONNECTION”),则以为服务端要主动断开连接,调用 disconnectFromHost() 方法断开连接。
重要功能和用法
- 1 包罗须要的头文件
在利用 QTcpSocket 之前,需要包罗相应的头文件,并在 .pro 文件中添加 QT += network 以引入网络模块。
- #include <QtNetwork/QTcpSocket>
复制代码
- QTcpSocket *socket = new QTcpSocket(this);
复制代码
- socket->connectToHost(QHostAddress::LocalHost, 12345);
- // 可以使用 waitForConnected 等待连接成功
- if (socket->waitForConnected()) {
- qDebug() << "Connected to server!";
- } else {
- qDebug() << "Connection failed!";
- }
复制代码
- QByteArray data = "Hello, server!";
- socket->write(data);
- // 可以使用 waitForBytesWritten 等待数据发送完成
- if (socket->waitForBytesWritten()) {
- qDebug() << "Data sent successfully!";
- }
复制代码
- // 连接 readyRead 信号到槽函数
- connect(socket, &QTcpSocket::readyRead, this, [socket]() {
- QByteArray data = socket->readAll();
- qDebug() << "Received data:" << data;
- });
复制代码
- socket->disconnectFromHost();
- // 可以使用 waitForDisconnected 等待断开连接完成
- if (socket->waitForDisconnected()) {
- qDebug() << "Disconnected from server!";
- }
复制代码
- connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
- [](QAbstractSocket::SocketError socketError) {
- qDebug() << "Socket error:" << socketError;
- });
- // 获取错误信息
- qDebug() << "Error message:" << socket->errorString();
复制代码 注意事项
- 上述示例中的错误码判断和特定消息判断只是一种常见的方式,具体的判断逻辑需要根据实际的业务需求和服务端的实现举行调解。
- 确保服务端和客户端对断开连接的消息和状态处置惩罚告竣同等,避免出现误解。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |